Di bawah skenario apa yang ingin digunakan seseorang
public async Task AsyncMethod(int num)
dari pada
public async void AsyncMethod(int num)
Satu-satunya skenario yang bisa saya pikirkan adalah jika Anda membutuhkan tugas untuk dapat melacak kemajuannya.
Selain itu, dalam metode berikut, apakah async dan menunggu kata kunci tidak perlu?
public static async void AsyncMethod2(int num)
{
await Task.Factory.StartNew(() => Thread.Sleep(num));
}
c#
asynchronous
.net-4.5
pengguna981225
sumber
sumber
Foo()
akan menjadiFooAsync()
.Thread.Sleep
dengan tugas-tugas Anda, Anda harusawait Task.Delay(num)
sebaliknyaTask.Delay
adalah tidakTask.AsyncDelay
semua metode dalam tugas adalah Asyncasync void
gantinyaasync Task
. Metode macet karena menggunakan objek konteks Kerangka Entitas yang dideklarasikan sebagai anggota controller dibuang sebelum metode selesai dieksekusi. Kerangka kerja membuang controller sebelum metode selesai dieksekusi. Saya mengubah metode menjadi Tugas async dan berhasil.Jawaban:
1) Biasanya, Anda ingin mengembalikan a
Task
. Pengecualian utama seharusnya ketika Anda harus memilikivoid
tipe pengembalian (untuk acara). Jika tidak ada alasan untuk melarang penelepon memilikiawait
tugas Anda, mengapa tidak mengizinkannya?2)
async
metode yang mengembalikanvoid
khusus dalam aspek lain: mereka mewakili operasi async tingkat atas , dan memiliki aturan tambahan yang ikut bermain ketika tugas Anda mengembalikan pengecualian. Cara termudah untuk menunjukkan perbedaannya adalah dengan contoh:f
Pengecualian selalu "diamati". Pengecualian yang meninggalkan metode asinkron tingkat atas hanya diperlakukan seperti pengecualian lain yang tidak ditangani.g
Pengecualian tidak pernah diamati. Ketika pengumpul sampah datang untuk membersihkan tugas, ia melihat bahwa tugas menghasilkan pengecualian, dan tidak ada yang menangani pengecualian. Ketika itu terjadi,TaskScheduler.UnobservedTaskException
pawang berlari. Anda seharusnya tidak pernah membiarkan ini terjadi. Untuk menggunakan contoh Anda,Ya, gunakan
async
dan diawait
sini, mereka memastikan metode Anda masih berfungsi dengan benar jika ada pengecualian.untuk informasi lebih lanjut lihat: http://msdn.microsoft.com/en-us/magazine/jj991977.aspx
sumber
f
alih-alihg
dalam komentar saya. Pengecualian darif
diteruskan keSynchronizationContext
.g
akan naikUnobservedTaskException
, tetapi prosesUTE
tidak lagi macet jika tidak ditangani. Ada beberapa situasi di mana itu dapat diterima untuk memiliki "pengecualian asinkron" seperti ini yang diabaikan.WhenAny
beberapaTask
s yang menghasilkan pengecualian. Anda sering hanya perlu menangani yang pertama, dan Anda sering ingin mengabaikan yang lain.WhenAny
di awal apakah tidak apa-apa untuk mengabaikan pengecualian lain: kasus penggunaan utama yang saya miliki untuk itu masih berakhir menunggu tugas yang tersisa ketika ada selesai , dengan atau tanpa pengecualian.Saya telah menemukan artikel yang sangat berguna tentang ini
async
danvoid
ditulis oleh Jérôme Laban: https://jaylee.org/archive/2012/07/08/c-sharp-async-tips-and-tricks-part-2-async-void .htmlIntinya adalah bahwa
async+void
can crash sistem dan biasanya harus digunakan hanya pada event handler sisi UI.sumber
Saya mendapat ide yang jelas dari pernyataan ini.
Pengecualian dari Metode Void Async Tidak Dapat Ditangkap dengan Catch
Pengecualian ini dapat diamati menggunakan AppDomain.UnhandledException atau acara catch-all yang serupa untuk aplikasi GUI / ASP.NET, tetapi menggunakan peristiwa itu untuk penanganan pengecualian reguler adalah resep untuk ketidakteraturan (ini membuat crash aplikasi).
Metode void Async memiliki semantik penulisan yang berbeda. Metode Async mengembalikan Tugas atau Tugas dapat dengan mudah dikomposisikan menggunakan menunggu, Task.WhenAny, Task.WhenAll dan sebagainya. Metode async yang mengembalikan batal tidak memberikan cara mudah untuk memberi tahu kode panggilan yang telah mereka selesaikan. Sangat mudah untuk memulai beberapa metode batal asinkron, tetapi tidak mudah untuk menentukan kapan mereka selesai. Metode batal async akan memberi tahu SynchronizationContext mereka ketika mereka mulai dan selesai, tetapi SynchronizationContext kustom adalah solusi kompleks untuk kode aplikasi reguler.
Metode Async Void berguna saat menggunakan pengendali acara sinkron karena mereka menaikkan pengecualian mereka langsung pada SynchronizationContext, yang mirip dengan bagaimana perilaku penangan sinkron berperilaku
Untuk lebih jelasnya periksa tautan ini https://msdn.microsoft.com/en-us/magazine/jj991977.aspx
sumber
Masalah dengan memanggil async void adalah bahwa Anda bahkan tidak mendapatkan tugas kembali, Anda tidak memiliki cara untuk mengetahui kapan tugas fungsi telah selesai (lihat https://blogs.msdn.microsoft.com/oldnewthing/20170720-00/ ? p = 96655 )
Berikut adalah tiga cara untuk memanggil fungsi async:
sumber
Saya pikir Anda dapat menggunakan
async void
untuk memulai operasi latar belakang juga, asalkan Anda berhati-hati untuk menangkap pengecualian. Pikiran?sumber
Jawaban saya sederhana, Anda tidak dapat menunggu metode kosong
Jadi, jika metode ini async lebih baik menunggu, karena Anda bisa kehilangan keuntungan async.
sumber
Menurut dokumentasi Microsoft , sebaiknya TIDAK PERNAH digunakan
async void
sumber