有兩種啟動方式:
var taskForAction = new Task(() => { //do something }); taskForAction.Start();注:構造所有的重載并沒有傳入Func函數的,而且我們這個時候看線程池中活動線程數會發現改變
//打印線程池中線程活動數 PRintAvailabeWorkThreadNum(); var taskForAction = new Task(() => { //do something }); taskForAction.Start(); PrintAvailabeWorkThreadNum();
輸出結果:
//打印線程池中線程活動數 PrintAvailableWorkThreadNum(); var taskForAction = Task.Run(() => Console.WriteLine("print string for Action")); var taskForFunc = Task.Run(() => "return string for Func<string>"); PrintAvailableWorkThreadNum(); //Result內部會調用Wait,所以這里不需要調 Console.WriteLine(taskForFunc.Result);同樣的,直接調用靜態方法來創建一個線程,并返回當前正在執行的線程副本以供我們調用,Result只有傳遞進去的是Func函數才會在返回的Task中存在,如果傳入的是Action函數,Result是不存在的, 這個時候線程活動數量也會改變。

已經在 【C#】線程協作式取消這章里面好好討論過如何去取消了,如何注冊回調函數等技術了.
我們有時候想在執行完一個任務以后,再開始做一個其他的任務,這個時候如果我們用Wait就會堵塞線程,如果我們用線程嵌套的方式去做,會浪費資源并損害的伸縮性。
//這樣會堵塞我們的線程 Task.Run(() => { //do something }).Wait(); Task.Run(() => { //do another thing }); //雖然不會堵塞線程了,但這樣會浪費資源 Task.Run(() => { Task.Run(() => { //do something }).Wait(); Task.Run(() => { //do another thing }); });CLR給我們提供了另一個方法:ContinueWith.
這個方法會不會堵塞當前的線程,并且會等第一個任務做好了以后再做第二個任務(當然可以開啟多個)
var t = Task.Run(() => { int index = 0; int count = 0; while (index != 5) { count += index; Console.WriteLine("Task:" + index++); Thread.Sleep(1 * 1000); } return count; }); t.ContinueWith(task => { //這里的參數Task,就是我們上面那個線程對象(t),可以用于獲取結果集,狀態等數據 Console.WriteLine("First continue task:" + task.Status); Console.WriteLine("First continue task:" + (task.Result + 100)+"/n"); }); t.ContinueWith(task => { Console.WriteLine("Second continue task:" + task.Status); Console.WriteLine("Second continue task:" + (task.Result - 100)); }); t.ContinueWith(task => { //Do another thing });需求肯定是很復雜的,比如我們希望在各種狀態(取消,完成,失敗等)情況下執行各種ContinueWith的方法,這個時候我們需要關注一個枚舉類型:TaskContinuationOptions, 以下給出官方的定義:

namespace System.Threading.Tasks{ // Summary: // Specifies the behavior for a task that is created by using the System.Threading.Tasks.Task.ContinueWith(System.Action<System.Threading.Tasks.Task>,System.Threading.CancellationToken,System.Threading.Tasks.TaskContinuationOptions,System.Threading.Tasks.TaskScheduler) // or System.Threading.Tasks.Task<TResult>.ContinueWith(System.Action<System.Threading.Tasks.Task<TResult>>,System.Threading.Tasks.TaskContinuationOptions) // method. [Serializable] [Flags] public enum TaskContinuationOptions { // Summary: // Default = "Continue on any, no task options, run asynchronously" Specifies // that the default behavior should be used. Continuations, by default, will // be scheduled when the antecedent task completes, regardless of the task's // final System.Threading.Tasks.TaskStatus. None = 0, // // Summary: // A hint to a System.Threading.Tasks.TaskScheduler to schedule a task in as // fair a manner as possible, meaning that tasks scheduled sooner will be more // likely to be run sooner, and tasks scheduled later will be more likely to // be run later. PreferFairness = 1, // // Summary: // Specifies that a task will be a long-running, course-grained Operation. It // provides a hint to the System.Threading.Tasks.TaskScheduler that oversubscription // may be warranted. LongRunning = 2, // // Summary: // Specifies that a task is attached to a parent in the task hierarchy. AttachedToParent = 4, // // Summary: // Specifies that an System.InvalidOperationException will be thrown if an attempt // is made to attach a child task to the created task. DenyChildAttach = 8, // // Summary: // Prevents the ambient scheduler from being seen as the current scheduler in // the created task. This means that operations like StartNew or ContinueWith // that are performed in the created task will see System.Threading.Tasks.TaskScheduler.Default // as the current scheduler. HideScheduler = 16, // // Summary: // In the case of continuation cancellation, prevents completion of the continuation // until the antecedent has completed. LazyCancellation = 32, // // Summary: // Specifies that the continuation task should not be scheduled if its antecedent // ran to completion. This option is not valid for multi-task continuations. NotOnRanToCompletion = 65536, // // Summary: // Specifies that the continuation task should not be scheduled if its antecedent // threw an unhandled exception. This option is not valid for multi-task continuations. NotOnFaulted = 131072, // // Summary: // Specifies that the continuation task should be scheduled only if its antecedent // was canceled. This option is not valid for multi-task continuations. OnlyOnCanceled = 196608, // // Summary: // Specifies that the continuation task should not be scheduled if its antecedent // was canceled. This option is not valid for multi-task continuations. NotOnCanceled = 262144, // // Summary: // Specifies that the continuation task should be scheduled only if its antecedent // threw an unhandled exception. This option is not valid for multi-task continuations. OnlyOnFaulted = 327680, // // Summary: // Specifies that the continuation task should be scheduled only if its antecedent // ran to completion. This option is not valid for multi-task continuations. OnlyOnRanToCompletion = 393216, // // Summary: // Specifies that the continuation
新聞熱點
疑難解答