線程是建立併發的底層工具,所以具備必定的侷限性。html
任務是可組合的——使用延續將它們串聯在一塊兒。它們可使用線程池減小啓動延遲,並且它們能夠經過TaskCompletionSource
使用回調方法,避免多個線程同時等待I/O密集操做。架構
一、任務是架構在線程之上的,也就是說任務最終仍是要拋給線程去執行。併發
二、任務跟線程不是一對一的關係,好比開10個任務並非說會開10個線程,這一點任務有點相似線程池,可是任務相比線程池有很小的開銷和精確的控制。異步
Task和Thread同樣,位於System.Threading命名空間下函數
與線程相比,Task
是一個更高級的抽象概念,它標識一個經過或不經過線程實現的併發操做。工具
Task 類的表示單個操做不返回一個值,一般以異步方式執行。 Task 對象是一個的中心思想 基於任務的異步模式 首次引入.NET Framework 4 中。 由於由執行工做 Task 對象一般以異步方式執行在線程池線程上而不是以同步方式在主應用程序線程,您可使用 Status 屬性,以及 IsCanceled, ,IsCompleted, ,和 IsFaulted 屬性,以肯定任務的狀態。 大多數狀況下,lambda 表達式用於指定的任務是執行的工做。spa
經過使用Task的構造函數來建立任務,並調用Start方法來啓動任務並執行異步操做。線程
static void Main(string[] args) { Console.WriteLine("主線程執行業務處理."); //建立任務 Task task = new Task(() => { Console.WriteLine("使用System.Threading.Tasks.Task執行異步操做."); for (int i = 0; i < 10; i++) { Console.WriteLine(i); } }); //啓動任務,並安排到當前任務隊列線程中執行任務 task.Start(); Console.WriteLine("主線程執行其餘處理"); }
從Framework 4.5開始,啓動一個由後臺線程實現的Task,也可使用靜態方法 Task.Run代理
Task task = Task.Run(() => { Thread.Sleep(2000); Console.WriteLine("Foo"); });
調用Wait
方法,能夠阻塞任務,直至任務完成,效果等同於Thread.Join
:code
Task task = Task.Run(() => { Thread.Sleep(2000); Console.WriteLine("Foo"); }); Console.WriteLine(task.IsCompleted); //False task.Wait();//阻塞,直至任務完成 Console.WriteLine(task.IsCompleted); //True Console.ReadLine();
Task<TResult>
容許任務返回一個值。調用Task.Run
,傳入一個Func<TResult>
代理(或者兼容的Lambda表達式),代替Action,就能夠得到一個Task<TResult>:
Task<int> task = Task.Run (() => { Console.WriteLine ("Foo"); return 3; }); int result = task.Result; // Blocks if not already finished Console.WriteLine (result); // 3
下面的例子建立一個任務,它使用LINQ就按前3百萬個整數(從2開始)中的素數個數:
Task<int> primeNumberTask = Task.Run(() => Enumerable.Range(2, 3000000).Count(n => Enumerable.Range(2, (int)Math.Sqrt(n) - 1).All(i => n % i > 0))); Console.WriteLine("Task running..."); Console.WriteLine("The answer is " + primeNumberTask.Result);
這段代碼會打印「Task running...」,而後幾秒鐘後打印216815。
Task.Delay
是Thread.Sleep
的異步版本
Task.Delay(5000).GetAwaiter().OnCompleted(()=>Console.WriteLine(42));
或者
Task.Delay(5000).ContinueWith(ant => Console.WriteLine(42));
參考資料:
https://www.jianshu.com/p/4444f2d77f3b
https://www.cnblogs.com/pengstone/archive/2012/12/23/2830238.html