ich ein einfaches WebAPI Projekt mit einem einzigen Controller und einer einzigen Methode erstellt:Warum tritt im Kontext von ASP.NET Task.Run (...) nicht auf, wenn beim Aufrufen einer asynchronen Methode ein Deadlock auftritt?
public static class DoIt
{
public static async Task<string> GetStrAsync(Uri uri)
{
using (var client = new HttpClient())
{
var str = await client.GetStringAsync(uri);
return str;
}
}
}
public class TaskRunResultController : ApiController
{
public string Get()
{
var task = Task.Run(() =>
DoIt.GetStrAsync(new Uri("http://google.com"))
);
var result = task.Result;
return result;
}
}
ich ein gutes Verständnis von Asynchron haben/abwarten und Aufgaben; fast religiös folgt Stephen Cleary. Nur die Existenz von .Result
macht mich ängstlich, und ich erwarte, dass dies zum Stillstand kommt. Ich verstehe, dass die Task.Run(...)
verschwenderisch ist, verursacht, dass ein Thread belegt wird, während auf die asynchrone DoIt()
fertig zu beenden.
Das Problem ist das ist nicht Deadlocking, und es gibt mir Herzklopfen. Ich sehe einige Antworten wie https://stackoverflow.com/a/32607091/1801382, und ich habe auch beobachtet, dass SynchronizationContext.Current
null ist, wenn das Lambda ausgeführt wird. Allerdings gibt es ähnliche Fragen zu meinen, warum der obige Code Deadlock ist, und ich habe gesehen, Deadlocks in Fällen auftreten, in denen ConfigureAwait(false)
verwendet wird (nicht erfassen den Kontext) in Verbindung mit .Result
.
Was gibt?
Danke, Stephen. Ich vermutete, dass die Antwort im Wesentlichen "das ist, weil die Aufgabe Task.Run den Kontext nicht erfordert", aber zögerte, dies "sicher" zu nennen. Ich verstehe die anderen Auswirkungen. Danke für das Blockierungsbeispiel; wie es jetzt 2017 ist, ist das seltenere Szenario immer noch gültig? Sie geben auch an, dass dies in GUI- oder ASP.NET-Code nicht vorkommen wird - in welchem Szenario _dies_ es Deadlock? – aholmes
Ja. 'await' verwendet immer noch' ExecuteSynchronously', sodass das seltenere Szenario immer noch gültig ist. In diesem Fall ist es ein Deadlock, bei dem zwei Thread-Pool-Threads auf einander warten. –