Natknąłem się na kilka najlepszych praktyk dotyczących programowania asynchronicznego przy użyciu słów kluczowych async
/ await
słów kluczowych języka C # (jestem nowy w C # 5.0).
Jedna z udzielonych rad była następująca:
Stabilność: poznaj konteksty synchronizacji
... Niektóre konteksty synchronizacji są niewłączane i jednowątkowe. Oznacza to, że w danym czasie można wykonać tylko jedną jednostkę pracy w kontekście. Przykładem tego jest wątek interfejsu użytkownika systemu Windows lub kontekst żądania ASP.NET. W tych jednowątkowych kontekstach synchronizacji łatwo jest się zablokować. Jeśli odrodzisz zadanie z kontekstu jednowątkowego, a następnie zaczekasz na to zadanie w kontekście, Twój oczekujący kod może blokować zadanie w tle.
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();
}
Jeśli spróbuję sam go przeanalizować, główny wątek odrodzi się do nowego MyWebService.GetDataAsync();
, ale ponieważ główny wątek tam czeka, czeka na wynik w GetDataAsync().Result
. W międzyczasie powiedzmy, że dane są gotowe. Dlaczego główny wątek nie kontynuuje swojej logiki kontynuacji i zwraca wynik w postaci ciągu GetDataAsync()
?
Czy ktoś może mi wyjaśnić, dlaczego w powyższym przykładzie jest impas? Nie mam pojęcia, na czym polega problem ...