從這篇文章開始,我想直接進入關於Task的一些內容,有時間再回顧Threadpool的相關內容。
我一開始接觸Task就覺得他和Thread很像,都是開新的線程。但是兩者有很多區別,其中比較明顯的是:Task創建的是線程池任務,而Thread默認創建的是前臺任務。
同Thread一樣,Task可以使用lambda表達式來構造action,作爲Task的構造函數參數。如下:
1、先定義一個函數TaskMethod,他接受name作爲字符串參數。
static void TaskMethod(string name)
{
Console.WriteLine("Task {0} 運行在線程id爲{1}的線程上. 是否是線程池中線程?:{2}",
name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
}
2、新建Task實例,並且Start():
var t1 = new Task(() => TaskMethod("Task 1"));
t1.Start();
因爲Task接受無參數和返回值的Action作爲構造器參數,因此此處可以使用如上的lambda表達式,在表達式中傳參"Task 1"。
運行結果如下:
可以很明顯的看出,該Task(t1)運行在線程池中。
必須要指出的是,線程池一般只運行執行時間較短的異步操作,需要長時間執行的操作儘量不要使用線程池。
除了上面這種開Task的方法,還有兩種常見的用法,分別是 Task.Run() 和 Task.Factory.StartNew()。兩者的區別在於後者能傳入一些額外參數,以豐富Task的運行選項。例如:
Task.Run(() => TaskMethod("Task 3"));
Task.Factory.StartNew(() => TaskMethod("Task 4"));
Task.Factory.StartNew(() => TaskMethod("Task 5"), TaskCreationOptions.LongRunning);
第二句則使用了Task.Factory.StartNew()默認方法,最後一句加入了選項“LongRunning”,意味着該任務將長時間運行,因此他不是在線程池中執行。
結果如下:
注意:Task的運行有一定的隨機性,開始次序會有變化!