Meine Methode kehrt zurück Task
. Ich möchte warten, bis es fertig ist. Was soll ich verwenden
.Wait()
oder .GetAwaiter().GetResult()
? Was ist der Unterschied zwischen ihnen?
Meine Methode kehrt zurück Task
. Ich möchte warten, bis es fertig ist. Was soll ich verwenden
.Wait()
oder .GetAwaiter().GetResult()
? Was ist der Unterschied zwischen ihnen?
Antworten:
Beides ist ein synchrones Warten auf das Ergebnis der Operation (und Sie sollten diese nach Möglichkeit vermeiden).
Der Unterschied besteht hauptsächlich in der Behandlung von Ausnahmen. Mit Wait
ist die Ablaufverfolgung des Ausnahmestapels unverändert und stellt den tatsächlichen Stapel zum Zeitpunkt der Ausnahme dar. Wenn Sie also einen Code haben, der auf einem Thread-Pool-Thread ausgeführt wird, haben Sie einen Stapel wie
ThreadPoolThread.RunTask
YourCode.SomeWork
Auf der anderen Seite .GetAwaiter().GetResult()
wird der Stack-Trace überarbeitet, um den gesamten asynchronen Kontext zu berücksichtigen. Dabei wird ignoriert, dass einige Teile des Codes auf dem UI-Thread und einige auf einem ThreadPool-Thread ausgeführt werden und andere einfach asynchrone E / A sind. Ihre Stapelverfolgung spiegelt also einen synchronen Schritt durch Ihren Code wider :
TheSyncMethodThatWaitsForTheAsyncMethod
YourCode.SomeAsyncMethod
SomeAsync
YourCode.SomeWork
Dies macht Ausnahme-Stack-Traces, gelinde gesagt, viel nützlicher. Sie können sehen, wo im Kontext Ihrer AnwendungYourCode.SomeWork
aufgerufen wurde , und nicht "wie sie physisch ausgeführt wurde".
Ein Beispiel dafür ist die Referenzquelle (natürlich nicht vertraglich).
TaskAwaiter
ist ein Implementierungsdetail. Auf der anderen Seite ist der Mechanismus "Warten / Warten" dokumentiert und verwendet die Enten-Typisierung - GetAwaiter
ist await
wie zu GetEnumerator
ist foreach
oder Dispose
ist zu using
. All dies ist in der C # -Spezifikation unabhängig vom verwendeten Kellner definiert. Beachten Sie, dass dies Task.GetAwaiter
"eher für die Verwendung durch den Compiler als für die Verwendung im Anwendungscode vorgesehen ist". Aber der Punkt ist, dass die beabsichtigte Verwendung darin besteht, ein await
, nicht Wait()
noch GetAwaiter().GetResult()
- aber GetResult
gibt Ihnen schönere Stapel, wenn Sie es brauchen.