2013-03-22 2 views
0

Здесь я использую методы, описанные в этой статье Await Tasks in C#4 using Iterators, для тиражирования с использованием async и await ключевых слов максимально близко к C# 5.Ожидание задач с использованием итераторов

Я наткнулся на проблему, которую я считаю такой же, как тот, который, кажется, придумать обычно при использовании GetResponseAsync() в C# 5 see question, как всякий раз, когда я пытаюсь использовать эквивалентный метод расширения yield return выскакивает из моего IEnumerable<Task> , Однако у меня нет метода ConfigureAwait(false).

Может ли кто-нибудь увидеть способ решить эту проблему?

Мой код:

/// <summary> 
/// Processes the image. 
/// </summary> 
/// <param name="context"> 
/// the <see cref="T:System.Web.HttpContext">HttpContext</see> 
/// object that provides references to the intrinsic server objects 
/// </param> 
private /*async*/ void ProcessImageAsync(HttpContext context) 
{ 
    this.ProcessImageAsyncTask(context).ToTask(); 
} 

/// <summary> 
/// Processes the image. 
/// </summary> 
/// <param name="context"> 
/// the <see cref="T:System.Web.HttpContext">HttpContext</see> 
/// object that provides references to the intrinsic server objects 
/// </param> 
/// <returns> 
/// The <see cref="IEnumerable{Task}"/>. 
/// </returns> 
private IEnumerable<Task> ProcessImageAsyncTask(HttpContext context) 
{ 
    // Code ommited that works out the url 
    Uri uri = new Uri(path); 

    HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(uri); 

    Task<WebResponse> responseTask = webRequest.GetResponseAsync(); 
    //################################################################// 
    //The method appears to be jumping out of the method here on yield 
    //################################################################// 
    yield return responseTask; 

    // Code that runs other tasks 

    yield break; 
} 

Я добавляю соответствующие методы расширения как Github Gist, чтобы сделать этот вопрос более читаемым.

+1

Рассматривали ли вы [Microsoft.Bcl.Async] (Http: // nuget.org/packages/Microsoft.Bcl.Async/)? –

+0

Я этого не видел. Я пытался уменьшить количество зависимостей, как и для библиотеки, но я обязательно проверю это. –

+0

Если вы используете VS2012, 'Microsoft.Bcl.Async' - это путь. Если вы застряли с VS2010, это не сработает. –

ответ

0

Я подозреваю, что проблема заключается в том, что продолжение запланировано с использованием TaskScheduler.FromCurrentSynchronizationContext. Она должна быть достаточно простой, чтобы добавить еще одну перегрузку, чтобы избежать этого:

public static Task<TResult> ToTask<TResult>(this IEnumerable<Task> tasks, TaskScheduler taskScheduler) 
{ 
    var taskEnumerator = tasks.GetEnumerator(); 
    var completionSource = new TaskCompletionSource<TResult>(); 

    // Clean up the enumerator when the task completes. 
    completionSource.Task.ContinueWith(t => taskEnumerator.Dispose(), taskScheduler); 

    ToTaskDoOneStep(taskEnumerator, taskScheduler, completionSource, null); 
    return completionSource.Task; 
} 

public static Task<TResult> ToTask<TResult>(this IEnumerable<Task> tasks) 
{ 
    var taskScheduler = SynchronizationContext.Current == null 
     ? TaskScheduler.Default 
     : TaskScheduler.FromCurrentSynchronizationContext(); 

    return ToTask<TResult>(tasks, taskScheduler); 
} 

Ваш код будет затем вызвать другую перегрузку:

private /*async*/ void ProcessImageAsync(HttpContext context) 
{ 
    ProcessImageAsyncTask(context).ToTask(TaskScheduler.Default); 
} 
Смежные вопросы