Mi sono imbattuto in alcune best practice per la programmazione asincrona utilizzando le parole chiave async
/ di c # await
(sono nuovo in c # 5.0).
Uno dei consigli dati è stato il seguente:
Stabilità: conosci i tuoi contesti di sincronizzazione
... Alcuni contesti di sincronizzazione sono non rientranti e a thread singolo. Ciò significa che solo un'unità di lavoro può essere eseguita nel contesto in un dato momento. Un esempio di ciò è il thread dell'interfaccia utente di Windows o il contesto della richiesta ASP.NET. In questi contesti di sincronizzazione a thread singolo, è facile bloccarsi. Se si genera un'attività da un contesto a thread singolo, quindi si attende quell'attività nel contesto, il codice di attesa potrebbe bloccare l'attività in background.
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();
}
Se provo a sezionarlo da solo, il thread principale viene generato in uno nuovo in MyWebService.GetDataAsync();
, ma poiché il thread principale attende lì, attende il risultato in GetDataAsync().Result
. Nel frattempo, diciamo che i dati sono pronti. Perché il thread principale non continua la sua logica di continuazione e restituisce un risultato di stringa da GetDataAsync()
?
Qualcuno può spiegarmi perché c'è un punto morto nell'esempio sopra? Sono completamente all'oscuro di quale sia il problema ...