Apa perbedaan antara .Wait () vs .GetAwaiter (). GetResult ()?

89

Metode saya kembali Task. Saya ingin menunggu sampai selesai. Apa yang harus saya gunakan .Wait()atau .GetAwaiter().GetResult()? Apa perbedaan di antara keduanya?


sumber

Jawaban:

110

Keduanya adalah penantian sinkron untuk hasil operasi (dan Anda harus menghindarinya jika memungkinkan).

Perbedaannya terutama dalam menangani pengecualian. Dengan Wait, pelacakan tumpukan pengecualian tidak berubah dan mewakili tumpukan sebenarnya pada saat pengecualian, jadi jika Anda memiliki potongan kode yang berjalan pada utas kumpulan benang, Anda akan memiliki tumpukan seperti

ThreadPoolThread.RunTask
YourCode.SomeWork

Di sisi lain, .GetAwaiter().GetResult()akan mengerjakan ulang pelacakan tumpukan untuk mempertimbangkan semua konteks asinkron, mengabaikan bahwa beberapa bagian kode dieksekusi pada utas UI, dan beberapa di utas ThreadPool, dan beberapa hanya I / O asinkron. Jadi pelacakan tumpukan Anda akan mencerminkan langkah seperti sinkronisasi melalui kode Anda :

TheSyncMethodThatWaitsForTheAsyncMethod
YourCode.SomeAsyncMethod
SomeAsync
YourCode.SomeWork

Ini cenderung membuat jejak tumpukan pengecualian jauh lebih berguna, untuk sedikitnya. Anda dapat melihat di mana YourCode.SomeWorkdipanggil dalam konteks aplikasi Anda , bukan "cara fisiknya dijalankan".

Contoh cara kerjanya ada di sumber referensi (non-kontrak, tentu saja).

Luaan
sumber
6
Task.GetAwaiter () mengembalikan TaskAwaiter . Namun, dokumen untuk TaskAwaiter.GetResult () menyarankan: "API ini mendukung infrastruktur produk dan tidak dimaksudkan untuk digunakan secara langsung dari kode Anda." Bisakah anda berkomentar
DavidRR
24
@DavidRR Keseluruhan TaskAwaiteradalah detail implementasi. Di sisi lain, mekanisme awaitable / awaiter didokumentasikan, dan menggunakan duck-Typing - GetAwaiteris to awaitas GetEnumeratoris to foreachatau Disposeis to using. Semua ini didefinisikan dalam spesifikasi C # terlepas dari awaiter tertentu yang digunakan - catatan yang Task.GetAwaiter"ditujukan untuk penggunaan kompilator daripada untuk digunakan dalam kode aplikasi." Tetapi intinya adalah bahwa tujuan penggunaan adalah untuk melakukan await, bukan Wait()atau GetAwaiter().GetResult()- tetapi GetResultmemberi Anda tumpukan yang lebih bagus jika Anda membutuhkannya.
Luaan