Kedua jawaban tidak menyebutkan yang ditunggu-tunggu Task.WhenAll
:
var task1 = DoWorkAsync();
var task2 = DoMoreWorkAsync();
await Task.WhenAll(task1, task2);
Perbedaan utama antara Task.WaitAll
dan Task.WhenAll
adalah bahwa yang pertama akan memblokir (mirip dengan menggunakan Wait
pada satu tugas) sedangkan yang terakhir tidak akan dan dapat ditunggu, menghasilkan kontrol kembali ke pemanggil sampai semua tugas selesai.
Lebih dari itu, penanganan pengecualian berbeda:
Task.WaitAll
:
Setidaknya satu instance Task dibatalkan - atau pengecualian dilemparkan selama eksekusi setidaknya satu instance Task. Jika tugas dibatalkan, AggregateException berisi OperationCanceledException dalam koleksi InnerExceptions-nya.
Task.WhenAll
:
Jika salah satu dari tugas yang disediakan menyelesaikan dalam kondisi yang salah, tugas yang dikembalikan juga akan selesai dalam keadaan yang salah, di mana pengecualiannya akan berisi agregasi dari set pengecualian yang terbuka dari masing-masing tugas yang disediakan.
Jika tidak ada tugas yang diberikan salah tetapi setidaknya salah satu dari mereka dibatalkan, tugas yang dikembalikan akan berakhir pada status Dibatalkan.
Jika tidak ada tugas yang salah dan tidak ada tugas yang dibatalkan, tugas yang dihasilkan akan berakhir pada status RanToCompletion. Jika array / enumerable yang disediakan tidak berisi tugas, tugas yang dikembalikan akan segera beralih ke status RanToCompletion sebelum dikembalikan ke pemanggil.
await Task.WhenAll(task1, task2);
?Task.WhenAll
tidak memulai tugas untuk Anda. Anda harus memberi mereka "panas", artinya sudah dimulai.StartNew
dan memutar tugas baru dengan menunggu secara tidak sinkron pada semuanya?Anda dapat membuat banyak tugas seperti:
sumber
Pilihan terbaik yang pernah saya lihat adalah metode ekstensi berikut:
Sebut saja seperti ini:
Atau dengan lambda async:
sumber
Anda dapat menggunakan
WhenAll
yang akan mengembalikan yang ditunggu-tungguTask
atauWaitAll
yang tidak memiliki tipe pengembalian dan akan memblokir eksekusi kode lebih lanjut secara simultanThread.Sleep
sampai semua tugas selesai, dibatalkan atau salah.Contoh
Jika Anda ingin menjalankan tugas dalam urutan praticular, Anda bisa mendapatkan inspirasi dari server ini .
sumber
await
untuk setiap operasi dan pada saat yang sama menggunakanWaitAll
atauWhenAll
. Bukankah seharusnya tugasTask[]
inisialisasi tanpaawait
?Apakah Anda ingin rantai
Task
s, atau mereka dapat dipanggil secara paralel?Untuk merantai
Lakukan saja sesuatu seperti
dan jangan lupa untuk memeriksa
Task
contoh sebelumnya di masingContinueWith
- masing karena mungkin salah.Untuk cara paralel
Metode paling sederhana yang saya temui:
Parallel.Invoke
Kalau tidak adaTask.WaitAll
atau Anda bahkan dapat menggunakanWaitHandle
s untuk melakukan hitung mundur ke nol tindakan yang tersisa (tunggu, ada kelas baru:)CountdownEvent
, atau ...sumber
Ini adalah bagaimana saya melakukannya dengan Fungsi array <> :
sumber
Namun jawaban lain ... tapi saya biasanya menemukan diri saya dalam sebuah kasus, ketika saya perlu memuat data secara bersamaan dan memasukkannya ke dalam variabel, seperti:
sumber
LoadCatsAsync()
danLoadDogAsync()
hanya panggilan basis data, mereka terikat IO.Task.Run()
adalah untuk pekerjaan yang terikat CPU; itu menambah biaya tambahan yang tidak perlu jika semua yang Anda lakukan menunggu jawaban dari server database. Jawaban yang diterima Yuval adalah cara yang tepat untuk pekerjaan yang terikat IO.Saya menyiapkan sepotong kode untuk menunjukkan kepada Anda bagaimana menggunakan tugas untuk beberapa skenario ini.
sumber