ความแตกต่างระหว่างTask.WaitAll()
และTask.WhenAll()
จาก Async CTP คืออะไร? คุณสามารถให้รหัสตัวอย่างเพื่อแสดงกรณีการใช้ที่แตกต่างกันได้หรือไม่?
ความแตกต่างระหว่างTask.WaitAll()
และTask.WhenAll()
จาก Async CTP คืออะไร? คุณสามารถให้รหัสตัวอย่างเพื่อแสดงกรณีการใช้ที่แตกต่างกันได้หรือไม่?
คำตอบ:
Task.WaitAll
บล็อกเธรดปัจจุบันจนกว่าทุกอย่างจะเสร็จสมบูรณ์
Task.WhenAll
ส่งคืนงานซึ่งแสดงถึงการกระทำของการรอจนกว่าทุกอย่างจะเสร็จสมบูรณ์
ซึ่งหมายความว่าจากวิธีการซิงค์คุณสามารถใช้:
await Task.WhenAll(tasks);
... ซึ่งหมายความว่าวิธีการของคุณจะดำเนินต่อไปเมื่อทุกอย่างเสร็จสมบูรณ์ แต่คุณจะไม่ผูกด้ายเพื่อรอจนกว่าจะถึงเวลานั้น
WhenAll
แต่นั่นไม่เหมือนกับการบล็อกเธรด
ในขณะที่คำตอบ JonSkeet อธิบายความแตกต่างในทางที่ดีมักจะมีความแตกต่างอื่น: การจัดการข้อยกเว้น
Task.WaitAll
โยนAggregateException
เมื่องานใด ๆ พ่นและคุณสามารถตรวจสอบข้อยกเว้นโยนทั้งหมด await
ในawait Task.WhenAll
unwraps AggregateException
'ผลตอบแทน' และมีเพียงข้อยกเว้นแรก
เมื่อโปรแกรมด้านล่างทำงานด้วยawait Task.WhenAll(taskArray)
เอาต์พุตจะเป็นดังนี้
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.
เมื่อโปรแกรมด้านล่างทำงานด้วยTask.WaitAll(taskArray)
เอาต์พุตจะเป็นดังนี้
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.
โปรแกรม:
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
ไม่ใช่ความแตกต่างระหว่างสองวิธี ทั้งการเผยแพร่การAggregateException
โยนโดยตรงหรือผ่านคุณสมบัติ ( Task.Exception
ทรัพย์สิน)
เป็นตัวอย่างของความแตกต่าง - ถ้าคุณมีงานทำสิ่งที่มีเธรด UI (เช่นงานที่แสดงถึงภาพเคลื่อนไหวในกระดานเรื่องราว) ถ้าคุณTask.WaitAll()
แล้วเธรด UI จะถูกบล็อกและ UI จะไม่ถูกอัปเดต หากคุณใช้await Task.WhenAll()
เธรด UI จะไม่ถูกบล็อกและ UI จะได้รับการอัปเดต
พวกเขาทำอะไร:
ความแตกต่างคืออะไร:
ใช้เมื่อใด:
WaitAll
เพราะฉันเข้าใจ
Task.WaitAll
หลังจากที่คุณทำงานอื่น ๆ ใช่มั้ย ฉันหมายถึงแทนที่จะเรียกมันทันทีหลังจากเริ่มงานของคุณ