Task是.NET4.0加入的,跟線程池ThreadPool的功能類似,用Task開啓新任務時,會從線程池中調用線程,而Thread每次實例化都會創建一個新的線程。任務(Task)是架構在線程之上的,也就是說任務最終還是要拋給線程(Thread)去執行。
任務Task和線程Thread的區別:
static void Main(string[] args) { for (int i = 0; i < 5; i++) { new Thread(Run1).Start(); } for (int i = 0; i < 5; i++) { Task.Run(() => { Run2(); }); } } static void Run1() { Console.WriteLine("Thread Id =" + Thread.CurrentThread.ManagedThreadId); } static void Run2() { Console.WriteLine("Task調用的Thread Id =" + Thread.CurrentThread.ManagedThreadId); }
Task使用方法
創建Task有兩種方式,一種是使用構造函數創建,另一種是使用 Task.Factory.StartNew 進行創建。如下代碼所示
1.使用構造函數創建Task
Task t1 = new Task(MyMethod);
2.使用Task.Factory.StartNew 進行創建Task
Task t1 = Task.Factory.StartNew(MyMethod);
多任務
public void test() { Task[] tasks = new Task[10]; for (int i = 0; i < 100; i++) { if (i % 2 == 0) { tasks[i] = new Task(test2, (object)i);//傳參,必須是obj } else { tasks[i] = new Task(test1); } tasks[i].Start(); } Task.WaitAll(tasks);//等待所有線程執行完成後纔會繼續往下執行
//Task.WaitAll(tasks,5000);//最多等待5秒
Response.Write("執行完成"); } private void test1() { //do } private void test2(object ourl) { //do }
連續任務
static void DownLoad(object str) { //下載文件 } static void ReadNews(Task obj) { //讀取文件 } static void Main(string[] args) { Task task = new Task(DownLoad, "人民日報"); Task task2 = task.ContinueWith(ReadNews); task.Start(); //DownLoad執行完才執行ReadNews }
限制Task最大數量
LimitedConcurrencyLevelTaskScheduler
這個TaskScheduler是微軟開源的一個任務調度器
static void Main(string[] args) {
//最大限制爲10 TaskFactory fac = new TaskFactory(new LimitedConcurrencyLevelTaskScheduler(10)); for (int i = 0; i < 1000; i++) { fac.StartNew(s => { Thread.Sleep(1000); Console.WriteLine("Current Index {0}, ThreadId {1}",s,Thread.CurrentThread.ManagedThreadId); }, i); } Console.ReadKey(); }
Task返回值
Task<string> t1 = Task.Factory.StartNew(() => "測試"); t1.Wait(); Console.WriteLine(t1.Result); Console.ReadLine(); //返回值可以是任意的類型