Я натрапив на кілька найкращих практик асинхронного програмування з використанням ключових слів 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()
?
Хтось може пояснити мені, чому у наведеному вище прикладі є глухий кут? Я абсолютно не знаю, в чому проблема ...