Apa perbedaan antara Task.WaitAll()
dan Task.WhenAll()
dari CTP Async? Bisakah Anda memberikan beberapa kode sampel untuk menggambarkan berbagai kasus penggunaan?
Apa perbedaan antara Task.WaitAll()
dan Task.WhenAll()
dari CTP Async? Bisakah Anda memberikan beberapa kode sampel untuk menggambarkan berbagai kasus penggunaan?
Jawaban:
Task.WaitAll
memblokir utas saat ini sampai semuanya selesai.
Task.WhenAll
mengembalikan tugas yang mewakili tindakan menunggu sampai semuanya selesai.
Itu berarti bahwa dari metode async, Anda dapat menggunakan:
await Task.WhenAll(tasks);
... yang berarti metode Anda akan berlanjut ketika semuanya selesai, tetapi Anda tidak akan mengikat utas untuk hanya berkeliaran sampai saat itu.
WhenAll
, tapi itu tidak sama dengan memblokir utas.
Sementara jawaban JonSkeet menjelaskan perbedaan dalam cara yang biasanya sangat baik ada perbedaan lain: penanganan pengecualian .
Task.WaitAll
melempar AggregateException
ketika salah satu tugas melempar dan Anda dapat memeriksa semua pengecualian yang dilemparkan. The await
di await Task.WhenAll
unwraps yang AggregateException
dan 'kembali' hanya pengecualian pertama.
Ketika program di bawah ini dijalankan dengan await Task.WhenAll(taskArray)
output adalah sebagai berikut.
19/11/2016 12:18:37 AM: Task 1 started
19/11/2016 12:18:37 AM: Task 3 started
19/11/2016 12:18:37 AM: Task 2 started
Caught Exception in Main at 19/11/2016 12:18:40 AM: Task 1 throwing at 19/11/2016 12:18:38 AM
Done.
Ketika program di bawah ini dijalankan dengan Task.WaitAll(taskArray)
output adalah sebagai berikut.
19/11/2016 12:19:29 AM: Task 1 started
19/11/2016 12:19:29 AM: Task 2 started
19/11/2016 12:19:29 AM: Task 3 started
Caught AggregateException in Main at 19/11/2016 12:19:32 AM: Task 1 throwing at 19/11/2016 12:19:30 AM
Caught AggregateException in Main at 19/11/2016 12:19:32 AM: Task 2 throwing at 19/11/2016 12:19:31 AM
Caught AggregateException in Main at 19/11/2016 12:19:32 AM: Task 3 throwing at 19/11/2016 12:19:32 AM
Done.
Program:
class MyAmazingProgram
{
public class CustomException : Exception
{
public CustomException(String message) : base(message)
{ }
}
static void WaitAndThrow(int id, int waitInMs)
{
Console.WriteLine($"{DateTime.UtcNow}: Task {id} started");
Thread.Sleep(waitInMs);
throw new CustomException($"Task {id} throwing at {DateTime.UtcNow}");
}
static void Main(string[] args)
{
Task.Run(async () =>
{
await MyAmazingMethodAsync();
}).Wait();
}
static async Task MyAmazingMethodAsync()
{
try
{
Task[] taskArray = { Task.Factory.StartNew(() => WaitAndThrow(1, 1000)),
Task.Factory.StartNew(() => WaitAndThrow(2, 2000)),
Task.Factory.StartNew(() => WaitAndThrow(3, 3000)) };
Task.WaitAll(taskArray);
//await Task.WhenAll(taskArray);
Console.WriteLine("This isn't going to happen");
}
catch (AggregateException ex)
{
foreach (var inner in ex.InnerExceptions)
{
Console.WriteLine($"Caught AggregateException in Main at {DateTime.UtcNow}: " + inner.Message);
}
}
catch (Exception ex)
{
Console.WriteLine($"Caught Exception in Main at {DateTime.UtcNow}: " + ex.Message);
}
Console.WriteLine("Done.");
Console.ReadLine();
}
}
await t1; await t2; await t3;
vsawait Task.WhenAll(t1,t2,t3);
await
, bukan perbedaan antara dua metode. Keduanya menyebarkan AggregateException
, baik melempar secara langsung atau melalui properti ( Task.Exception
properti).
Sebagai contoh perbedaan - jika Anda memiliki tugas, lakukan sesuatu dengan utas UI (mis. Tugas yang mewakili animasi di Storyboard) jika Anda Task.WaitAll()
maka utas UI diblokir dan UI tidak pernah diperbarui. jika Anda gunakan await Task.WhenAll()
maka utas UI tidak diblokir, dan UI akan diperbarui.
Apa yang mereka lakukan:
Apa bedanya:
Gunakan kapan:
WaitAll
apa yang saya mengerti.
Task.WaitAll
setelah melakukan beberapa pekerjaan lain? Maksud saya, alih-alih memanggilnya segera setelah memulai tugas Anda.