用過.NET線程池的程式員都知道通過調用ThreadPool類的QueueUserWorkItem方法把要執行的代碼放入線程池去執行。由於.NET FCL的強大,使得這個操作極其簡便。但使用線程池有個明顯的不足之處,那就是我們無法擷取線程池執行方法的傳回值,因為WaitCallback委託的傳回值為void。註:WaitCallback委託的原型為:public delegate void WaitCallback(Object state)。
比如,我們有個方法代碼是這樣的:
public int Sum()
{
//此方法類比一個耗時操作
int sum = 0;
for (int num = 1; num <= 100; num++)
{
Thread.Sleep(5);
sum += num;
}
return sum;
}
假如這個方法可以加入線程池中去執行(實際上不能,因為不匹配WaitCallback委託),但我們也無法擷取執行的結果。隨著.NET4.0的發布,這個問題得到瞭解決,.NET 4.0提供了一個新功能,叫任務(Task),在System.Threading.Task命名空間下,有個Task類及其泛型版本Task<TResult>。我們可以把這個方法添加到任務,並可以獲得執行結果,示意代碼如下:
using System;
using System.Threading;
using System.Threading.Tasks;
namespace TaskDemo
{
class Program
{
static void Main(string[] args)
{
Task<int> task = new Task<int>(() => Sum());//建立任務執行個體
task.Start();//開始任務
Console.WriteLine("任務已開始");
task.Wait();//等待任務執行完成
Console.WriteLine(task.Result);
}
//此方法類比一個耗時操作
static int Sum()
{
Console.WriteLine("任務正在執行");
int sum = 0;
for (int num = 1; num <= 100; num++)
{
Thread.Sleep(5);
sum += num;
}
return sum;
}
}
}
任務(Task)確實是個好東東!這裡只對任務(Task)作個初步的介紹。由於我也只是剛接觸,感覺這是個非常有用的功能,於是忍不住就寫出來了,由於筆者水平有限,不足之處還望高手指點。
最後,非常感謝Jeffrey Richter給我們帶來的驚喜--《CLR via C#, Third Edition》。
參考文獻:《CLR via C#, Third Edition》,作者:Jeffrey Richter。