würde es die Aufgabe zweimal ausführen? Oder eine Exception werfen, weil bereits ausgeführt wird?
Nein und nein. Das einzige, was await
tut, ist Task.GetAwaiter
aufrufen, es verursacht nichts zu laufen. Wenn die Task bereits vollständig ausgeführt wurde, wird entweder der Wert extrahiert, wenn es sich um eine Task<T>
handelt, oder synchron zur nächsten Zeile ausgeführt, wenn es sich um eine Task
handelt, da es eine Optimierung für bereits abgeschlossene Tasks gibt.
Eine einfache Demo:
async Task Main()
{
var foo = FooAsync();
await foo;
await foo;
var bar = BarAsync();
var firstResult = await bar;
var secondResult = await bar;
Console.WriteLine(firstResult);
Console.WriteLine(secondResult);
}
public async Task FooAsync()
{
await Task.Delay(1);
}
public async Task<int> BarAsync()
{
await Task.Delay(1);
return 1;
}
Wenn Sie an die Zustandsmaschine selbst Drill-Down, werden Sie sehen:
this.<foo>5__1 = this.<>4__this.FooAsync();
taskAwaiter = this.<foo>5__1.GetAwaiter();
if (!taskAwaiter.IsCompleted)
{
this.<>1__state = 0;
this.<>u__1 = taskAwaiter;
M.<FooBar>d__0 <FooBar>d__ = this;
this.<>t__builder.AwaitUnsafeOnCompleted<TaskAwaiter, M.<FooBar>d__0>
(ref taskAwaiter, ref <FooBar>d__);
return;
}
Diese Optimierung überprüft zunächst den Abschluss der Aufgabe. Wenn die Aufgabe nicht abgeschlossen ist, ruft sie UnsafeOnCompleted
auf, wodurch die Fortsetzung registriert wird. Wenn es abgeschlossen ist, bricht es die switch
und geht an:
this.<>1__state = -2;
this.<>t__builder.SetResult();
die das Ergebnis für die zugrunde liegenden Task
setzt, und auf diese Weise Sie tatsächlich den Wert synchron bekommen.
Warum versuchst du es nicht? Es ist nicht schwer zu testen. – Enigmativity
Die wichtigste Erkenntnis hier ist, dass * erwarten keine Aufgabe * ausgeführt wird. Warten * wartet asynchron auf die Beendigung einer Aufgabe *. Daher der Name "erwarten". Es gibt einen hartnäckigen Mythos, der auf eine Aufgabe wartet, aber natürlich nicht; Sie haben bereits eine begonnene Aufgabe in der Hand, wenn Sie darauf warten. –
Der wahre Augenöffner für mich war das Konzept der "Fortsetzungen". Ich denke, ohne diese Einsicht ist es schwierig, "erwarten" zu begreifen. – Sentinel