1. 程式人生 > >【C#】48. Task WhenAll、WhenAny 建立任務的任務

【C#】48. Task WhenAll、WhenAny 建立任務的任務

Task中有幾個非常方便的並行執行任務的方式,比如WhenAll(當所有Task都執行完畢RanToCompletion)、WhenAny(只要有一個Task執行完畢)等等。本篇就來介紹一下WhenAll和WhenAny。

static int TaskMethod(string name, int seconds)
{
Console.WriteLine("Task {0} 執行線上程 {1} 上。是否是執行緒池執行緒: {2}",
name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
Thread.Sleep(TimeSpan.FromSeconds(seconds));
return 42 * seconds;
}
一、WhenAll
var firstTask = new Task<int>(() => TaskMethod("First Task", 3));
var secondTask = new Task<int>(() => TaskMethod("Second Task", 2));
var whenAllTask = Task.WhenAll(firstTask, secondTask);
whenAllTask.ContinueWith(t =>Console.WriteLine("The first answer is {0}, the second is {1}", t.Result[0], t.Result[1]),
TaskContinuationOptions.OnlyOnRanToCompletion
);

firstTask.Start();
secondTask.Start();

這裡設定了一個名字為whenAllTask的變數,他是用靜態方法Task.WhenAll建立的第三個任務。需要注意的是,由於是基於前面兩個任務建立的,因此返回的型別為Task<int[]>。在firstTask和secondTask執行完畢後(WhenAll),採用後續操作(ContinueWith),函式中的t其實也就是whenAllTask的傳參。後續操作打印出whenAllTask中的Result陣列成員,後續操作的狀態條件為whenAllTask的狀態為OnlyOnRanToCompletion


二、WhenAny

var tasks = new List<Task<int>>();
for (int i = 1; i < 4; i++)
{
int counter = i;
var task = new Task<int>(() => TaskMethod(string.Format("Task {0}", counter), counter));
tasks.Add(task);
task.Start();
}

while (tasks.Count > 0)
{
var completedTask = Task.WhenAny(tasks).Result;//這裡的Result是指代Task<int>!
tasks.Remove(completedTask);
Console.WriteLine("A task has been completed with result {0}.", completedTask.Result);
}

首先建立一個Task List,名字為tasks。而後依次向裡新增新任務例項,而且新任務的執行所需時間依次為1、2、3秒。而後,倫查tasks中的任務數量,在迴圈內建立completedTask任務,用來表示任一個在tasks中已經完成操作的Task,如果一個任務都沒執行完成,則completedTask。需要指出的是,這裡的Result和上例中的不同,上例中t.Result直接指代int[],即返回結果陣列;而這裡的WhenAny(tasks).Result指的是Task<int>,也就是完成的Task<int>例項