Bagaimana saya bisa menunggu void async
metode untuk menyelesaikan tugasnya?
misalnya, saya memiliki fungsi seperti di bawah ini:
async void LoadBlahBlah()
{
await blah();
...
}
sekarang saya ingin memastikan bahwa semuanya telah dimuat sebelum melanjutkan ke tempat lain.
c#
asynchronous
MBZ
sumber
sumber
await Task.Run(() => An_async_void_method_I_can_not_modify_now())
await Task.Run(() => blah())
menyesatkan. Ini tidak menunggu selesainya fungsi asyncblah
, itu hanya menunggu penciptaan (sepele) tugas, dan berlanjut segera sebelumblah()
selesai.Thread.Sleep
tidak async. Pertanyaan ini adalah tentang menunggu suatuasync void
fungsi, katakanlahasync void blah() { Task.Delay(10000); }
Jika Anda dapat mengubah tanda tangan fungsi
async Task
Anda, maka Anda dapat menggunakan kode yang disajikan di sinisumber
Solusi terbaik adalah menggunakan
async Task
. Anda harus menghindariasync void
karena beberapa alasan, salah satunya adalah kompabilitas.Jika metode tidak dapat dibuat untuk kembali
Task
(misalnya, itu adalah pengendali acara), maka Anda dapat menggunakanSemaphoreSlim
untuk memiliki sinyal metode ketika akan keluar. Pertimbangkan untuk melakukan ini difinally
blok.sumber
lakukan AutoResetEvent, panggil fungsi lalu tunggu AutoResetEvent dan kemudian atur di dalam async void ketika Anda tahu itu selesai.
Anda juga bisa menunggu pada Tugas yang kembali dari kekosongan async Anda
sumber
Anda tidak perlu melakukan apa pun secara manual,
await
kata kunci menjeda eksekusi fungsi sampaiblah()
kembali.T
adalah jenisblah()
pengembalian objekAnda tidak bisa benar
await
- benarvoid
fungsi jadiLoadBlahBlah()
tidak bisavoid
sumber
LoadBlahBlah()
sampai selesai, bukanblah()
Saya tahu ini adalah pertanyaan lama, tetapi ini masih merupakan masalah yang terus saya hadapi, namun masih belum ada solusi yang jelas untuk melakukan ini dengan benar ketika menggunakan async / menunggu dalam metode tanda tangan async void.
Namun, saya perhatikan bahwa. Tunggu () berfungsi dengan baik di dalam metode void.
dan karena async void dan void memiliki tanda tangan yang sama, Anda mungkin perlu melakukan hal berikut.
Async / wait yang cukup membingungkan tidak menghalangi pada kode selanjutnya.
Ketika Anda mendekompilasi kode Anda, tebakan saya adalah bahwa async void membuat Tugas internal (seperti Tugas async), tetapi karena tanda tangan tidak mendukung untuk mengembalikan tugas internal tersebut
ini berarti bahwa secara internal metode void async masih akan dapat "menunggu" metode async internal. tetapi secara eksternal tidak dapat mengetahui kapan tugas internal selesai.
Jadi kesimpulan saya adalah bahwa async void berfungsi sebagaimana mestinya, dan jika Anda memerlukan umpan balik dari Tugas internal, maka Anda harus menggunakan tanda tangan Tugas async sebagai gantinya.
semoga obrolan saya masuk akal bagi siapa pun yang juga mencari jawaban.
Sunting: Saya membuat beberapa contoh kode dan mendekompilasi untuk melihat apa yang sebenarnya terjadi.
Berubah menjadi (sunting: Saya tahu bahwa kode bodi tidak ada di sini tetapi di statemachine, tetapi statemachine pada dasarnya identik, jadi saya tidak repot menambahkannya)
AsyncVoidMethodBuilder atau AsyncTaskMethodBuilder tidak benar-benar memiliki kode apa pun dalam metode Mulai yang akan mengisyaratkan mereka untuk memblokir, dan akan selalu berjalan secara tidak sinkron setelah dijalankan.
artinya tanpa Tugas kembali, tidak akan ada cara untuk memeriksa apakah sudah selesai.
seperti yang diharapkan, ia hanya memulai Task yang menjalankan async, dan kemudian melanjutkan dalam kode. dan Tugas async, pertama memulai Tugas, dan kemudian mengembalikannya.
jadi saya kira jawaban saya adalah untuk tidak pernah menggunakan async void, jika Anda perlu tahu kapan tugas itu selesai, itulah tugas Async.
sumber