C# Task總結(異步操作+並行)


任務Task與線程Thread不可比。Task是為了利用多CPU多核的機制而將一個大任務不斷分解成小任務,這些任務具體由哪一個線程或當前線程執行由OS來決定。如果你想自己控制由哪一個Thread執行,要么自己定議task的scheduling, 要么自己來創建Thread來執行代碼。

1)task是根據自己需要調用線程

2)thread就是個基本單位

簡單地du說,thread是單核多線程,task是多核多線程

 /// <summary>
 /// 簡單的task創建方式演示
 /// </summary>
 private static void TaskCreatFun()
 {
     // 其一、通過傳統的 new 方式來實例化一個task對象,這種方式需要手動通過start來啟動
     Task newTask = new Task(() =>
     {
         Thread.Sleep(1000);
         Console.WriteLine($"Hello Engineer, 我是 new 的一個task,線程ID:Thread.CurrentThread.ManagedThreadId}");
     });

     // 啟動 tsak
     newTask.Start();

     // 其二、通過工廠 factory 來生成一個task對象,並自啟動
     Task factoryTask = Task.Factory.StartNew(() =>
     {
         Thread.Sleep(1000);
         Console.WriteLine($"Hello Engineer, 我是 factory 生產 的一個task,線程ID:Thread.CurrentThread.ManagedThreadId}");
     });

     // 其三、通過 Task.Run(Action action) 來創建一個自啟動task
     Task runTask = Task.Run(() =>
     {
         Thread.Sleep(1000);
         Console.WriteLine($"Hello Engineer, 我是 Task.Run 創建一個自啟動task,線程ID:Thread.CurrentThread.ManagedThreadId}");
     });
     runTask.RunSynchronously();

     Console.WriteLine($"Hello Engineer, 我是主線程啦!線程ID{Thread.CurrentThread.ManagedThreadId}");
 }

  Task回調

  a.某一個任務結束回調

 taskList.Add(taskFactory.StartNew(() => this.DoSomethingLong("btnTask_Click_002")));
 taskList.Add(taskFactory.StartNew(() => this.DoSomethingLong("btnTask_Click_001")));
 //回調ContinueWhenAny沒有那么精准,不一定是在某個線程完成之后發生
 taskList.Add(taskFactory.ContinueWhenAny(taskList.ToArray(), t =>      Console.WriteLine($"ContinueWhenAny {Thread.CurrentThread.ManagedThreadId.ToString("00")}")));

  b.所有任務結束回調

taskList.Add(taskFactory.ContinueWhenAll(taskList.ToArray(), tList => Console.WriteLine($"這里是ContinueWhenAll {Thread.CurrentThread.ManagedThreadId.ToString("00")}")));

  c.單個任務結束回調

Task task2 = taskFactory.StartNew(t => this.DoSomethingLong("btnTask_Click_005"), "煎餅果子").ContinueWith(t => Console.WriteLine($"這里是{t.AsyncState}的回調"));

  Task等待

Task.WaitAny(taskList.ToArray());//卡界面

Task.WaitAll(taskList.ToArray());//卡界面

  Task獲取返回結果

Task<int> intTask = taskFactory.StartNew(() => 123);
int iResult = intTask.Result;
Task<string> intTask = taskFactory.StartNew(() => "123");
int iResult = intTask.Result;

  Task同步執行

可以用task.RunSynchronously() 來同步執行,但是這種方式執行,只有通過new 實例化的task才有效,原因也很簡單,其他兩種方式創建task都已經自啟動執行了,不可能在來一個同步啟動執行吧。

也可以通過task.wait()來變相的實現同步執行效果,當然也可以用task.Result來變現的實現,原理很簡單,因為wait()和Result都是要阻塞主流程,直到task執行完畢

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM