多線程編程總結:三、Task的使用和意義

Task 

       創建每個線程需要佔用1MB的虛擬內存,並且線程過多會導致CPU耗費大量時間在切換不同線程上。所以在之前我們會使用線程池來自動分配線程。

       在.Net Framwork 4,TPL提供了一個新的方式去創建線程,那就是Task類,它告訴任務調度器有異步工作需要做,任務調度器有多重測量,但是默認是從線程池請求一個線程給Task類使用。

       Task類是異步執行一個工作任務,而委託(例如:Action)是同步執行一個工作任務。所以Task是將委託(Action)從同步執行模式轉變爲異步執行。

       Task.Run()是直接熱啓動,也就是立刻執行,而如果通過Task構造函數實例化的任務就是冷啓動,不會立即執行。熱啓動任務的狀態是不確定的。當遇上一組Task正在運行,而我們需要等待所有任務都完成時就會使用Task.WaitAll(),只需要等待任一任務完成就使用Task.WaitAny();

       如果我們想要這個任務返回一個結果,我們需要使用Task<T>類型異步運行一個Func<T>.例如:

            Task<string> task = Task.Run<string>(() => {
                return string.Empty;
            });

        任務結束之後,IsCompleted屬性設置爲true,但是該任務實際上運行可能是正常的,也可能是出錯結束。需要讀取Task.Status屬性得到具體狀態,其中只要Status爲RuntoCompletion / Canceled / Faulted,都會設置IsCompleted=true。

        Task.CurrentId是唯一性標識,在調試的時候非常有用,另外AsyncState可以爲任務關聯額外數據,將需要開啓這個Task的源對象或者某一些Target對象帶入Task內部。

 

控制流

        控制流實際上就是系統決定接下來要做什麼?例如Console.WriteLine(str.GetHashCode());那麼這句代碼的控制流就是首先計算出str的HashCode值,然後將這個返回值作爲WriteLine的參數,在這個過程中就產生了控制點的延續,實際上C#編程是控制流延續直到結束。任何給定代碼的延續實際上是分爲兩種可能,“正常”和“異常”。

        普通的同步操作是自上而下的延續控制流,但是異步任務是在原有的控制流上添加了一個新的分支維度,也就是原有的Task.Start()語句執行後,控制流繼續往下執行,同時Task委託的主體代碼也開始執行了,在原有控制流的基礎上增加了一條分支控制流開始執行。

 

Task.ContinueWith()

         使用CountinueWith()方法可以串行的鏈接運行任務,只有前面一個任務完成之後纔可以繼續完成第二個任務。同時該方法返回的也是Task對象,還可以繼續串接第三個任務,所以是可以鏈接任意長度的任務鏈的。

         ContinueWith()有很多重載,其中有一個ContinueWithOptions枚舉值可以提供多重串行運行可能性

枚舉值 具體應用
None 默認爲前面任務完成,不管任務狀態是什麼都運行下一個任務
PreferFairness 公平調度,不保證誰先運行
LongRunning 告訴調度器這是一個I/O受限的高延遲任務,調度器可先處理後面的其他工作,少用
AttachedToParent 指定任務連接到任務層次結構中的父任務
DenyChildAttach 試圖創建子任務將引發異常
NotOnRanToCompletion 如果延續任務的先驅任務成功完成,則不應該調度延續任務。
NotOnFaulted 如果延續任務的先驅任務失敗,引發了異常,則不應該調度延續任務。
NotOnCanceled 如果延續任務的先驅任務取消了,則不應該調度延續任務。
OnlyOnCanceled 如果延續任務的先驅任務取消了,才調度該延續任務。 
OnlyOnFaulted 如果延續任務的先驅任務失敗,引發了異常,才調度延續任務
OnlyOnRanToCompletion 如果延續任務的先驅任務成功完成,才應該調度延續任務。
ExecuteSynchronously 直接在先驅任務的線程上繼續運行,而無需重新從線程池拿線程。
HideScheduler 隱藏線程調度器
LazyCancellation

延續任務將監視取消的標誌的時間推遲到前驅任務結束之後。

有延續任務t1、t2、t3,其中t2任務在t1完成前取消了,那麼t3可能會在t1完成前開始,這個參數可以避免這種問題。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章