一、Task.WhenAll概述
在非同步編程中,經常會遇到需要等待多個任務全部完成後才能繼續執行的情況。.NET Framework 4.5為開發人員提供了Task.WhenAll方法來處理這種情況。Task.WhenAll方法返回一個Task,當傳入的所有任務完成時,該Task將被標記為已完成狀態。此外,返回Task的結果將是由傳入參數給出的所有Task的結果列表。如果傳入的任意一個任務失敗,則返回的Task也將失敗,其狀態為Faulted,並包含失敗任務的異常。
二、Task.WhenAll方法示例
static async Task Main(string[] args)
{
Task task1 = Task.Run(() => { Thread.Sleep(1000); Console.WriteLine("Task 1 finished"); });
Task task2 = Task.Run(() => { Thread.Sleep(2000); Console.WriteLine("Task 2 finished"); });
Task task3 = Task.Run(() => { Thread.Sleep(3000); Console.WriteLine("Task 3 finished"); });
await Task.WhenAll(task1, task2, task3);
Console.WriteLine("All tasks finished successfully");
}
在上述示例中,我們定義了三個Task:task1,task2和task3。task1休眠1秒鐘,task2休眠2秒鐘,task3休眠3秒鐘。最後我們使用Task.WhenAll等待三個任務全部完成並列印出”All tasks finished successfully”。這裡需要注意的是,我們使用await關鍵詞等待所有任務的完成。
三、Task.WhenAll和異常處理
當傳遞給Task.WhenAll的所有任務都成功完成時,返回的Task將標記為已完成狀態。然而,如果其中任意一個任務拋出異常,則返回的Task也將拋出相應異常。下面的示例演示了這種情況:
static async Task Main(string[] args)
{
Task task1 = Task.Run(() => { throw new Exception("Task 1 failed"); });
Task task2 = Task.Run(() => { Thread.Sleep(2000); Console.WriteLine("Task 2 finished"); });
Task task3 = Task.Run(() => { Thread.Sleep(3000); Console.WriteLine("Task 3 finished"); });
try
{
await Task.WhenAll(task1, task2, task3);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
在這個示例中,我們故意讓task1拋出異常。因此,當使用Task.WhenAll等待三個任務完成時,返回的Task將拋出與task1關聯的異常。catch塊將列印出異常消息。
四、Task.WhenAll和取消
有時,我們可能需要在某些情況下取消任務的執行。在這種情況下,我們可以使用CancellationTokenSource和CancellationToken來取消任務。下面是一個演示如何使用取消令牌的示例:
static async Task Main(string[] args)
{
var cts = new CancellationTokenSource();
var token = cts.Token;
Task task1 = Task.Run(() => { Thread.Sleep(10000); Console.WriteLine("Task 1 finished"); }, token);
Task task2 = Task.Run(() => { Thread.Sleep(20000); Console.WriteLine("Task 2 finished"); }, token);
Task task3 = Task.Run(() => { Thread.Sleep(30000); Console.WriteLine("Task 3 finished"); }, token);
await Task.WhenAny(task1, task2, task3);
cts.Cancel();
Console.WriteLine("Task cancelled");
}
在這個示例中,我們使用CancellationTokenSource和CancellationToken來取消任務。首先,我們定義了一個CancellationTokenSource並使用其Token作為任務的取消令牌。接下來,我們使用Task.WhenAny等待任何一個任務完成。一旦完成,我們將調用CancellationTokenSource的Cancel方法來取消所有任務的執行。
五、總結
在本文中,我們詳細介紹了Task.WhenAll方法。我們首先介紹了Task.WhenAll方法的概述,並通過示例演示了Task.WhenAll的用法。隨後,我們介紹了Task.WhenAll方法對異常的處理和如何使用CancellationToken來取消任務。如果你希望編寫高效的非同步代碼,那麼掌握Task.WhenAll將會非常有用。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/159594.html