Пример асинхронного ожидания / ожидания, который вызывает тупик
Я натолкнулся на некоторые лучшие практики для асинхронного программирования с использованием c #async
/await
ключевые слова (я новичок в c # 5.0).
Одним из советов было следующее:
Стабильность: знайте свои контексты синхронизации
... Некоторые контексты синхронизации не являются реентерабельными и однопоточными. Это означает, что в данный момент в контексте может быть выполнена только одна единица работы. Примером этого является поток пользовательского интерфейса Windows или контекст запроса ASP.NET. В этих однопоточных контекстах синхронизации легко заблокировать себя. Если вы порождаете задачу из однопоточного контекста, а затем ждите эту задачу в контексте, ваш код ожидания может блокировать фоновую задачу.
public ActionResult ActionAsync()
{
// DEADLOCK: this blocks on the async task
var data = GetDataAsync().Result;
return View(data);
}
private async Task<string> GetDataAsync()
{
// a very simple async method
var result = await MyWebService.GetDataAsync();
return result.ToString();
}
Если я попытаюсь разобрать его сам, основной поток появится в новомMyWebService.GetDataAsync();
, но так как главный поток там ждет, он ожидает результата вGetDataAsync().Result
, Между тем, говорят, что данные готовы. Почему основной поток не продолжает свою логику продолжения и возвращает строковый результат изGetDataAsync()
?
Может кто-нибудь объяснить, почему в приведенном выше примере тупик? Я совершенно не понимаю, в чем проблема ...