TaskCompletionSource的使用場景


 

Task類最適合表示計算密集型操作。默認地,為了提供有效的執行操作,它利用了.Net線程池中特殊的支持,同時也對異步計算何時,何地,如何執行提供了大量的控制。

生成計算受限的tasks有幾種方法。

  1. 在.Net 4中,啟動一個新的計算受限的task的主要方法是TaskFactory.StartNew(),該方法接受一個異步執行的委托(一般來說是一個Action或者一個Func<TResult>)。如果提供了一個Action,返回的Task就代表那個委托的異步執行操作。如果提供了一個Func<TResult>,就會返回一個Task<TResult>。存在StartNew()的重載,該重載接受CancellationToken,TaskCreationOptions,和TaskScheduler,這些都對task的調度和執行提供了細粒度的控制。作用在當前調度者的工廠實例可以作為Task類的靜態屬性,例如Task.Factory.StartNew()。
  2. 在.Net 4.5中,Task類型暴露了一個靜態的Run方法作為一個StartNew方法的捷徑,可以很輕松地使用它來啟動一個作用在線程池上的計算受限的task。從.Net 4.5開始,對於啟動一個計算受限的task,這是一個更受人喜歡的機制。當行為要求更多的細粒度控制時,才直接使用StartNew。
  3. Task類型公開了構造函數和Start方法。如果必須要有分離自調度的構造函數,這些就是可以使用的(正如先前提到的,公開的APIs必須只返回已經啟動的tasks)。
  4. Task類型公開了多個ContinueWith的重載。當另外一個task完成的時候,該方法會創建新的將被調度的task。該重載接受CancellationToken,TaskCreationOptions,和TaskScheduler,這些都對task的調度和執行提供了細粒度的控制。
  5. TaskFactory類提供了ContinueWhenAll 和ContinueWhenAny方法。當提供的一系列的tasks中的所有或任何一個完成時,這些方法會創建一個即將被調度的新的task。有了ContinueWith,就有了對於調度的控制和任務的執行的支持。  

 

        TaskCompletionSource生成Task的另一種方法.使用TaskCompletionSource很簡單,只需要實例化它即可。TaskCompletionSource有一個Task屬性,你可以對該屬性暴露的task做操作,比如讓它wait或者ContinueWith等操作。當然,這個task由TaskCompletionSource完全控制,相當於你可以對創建的Task提前做適當控制規則。

 

      使用TaskCompletionSource<TResult>類型創建的Tasks不應該直接被全部執行的線程返回。TaskCompletionSource<TResult>暴露了一個返回相關的Task<TResult>實例的Task屬性。該task的生命周期通過TaskCompletionSource<TResult>實例暴露的方法控制,換句話說,這些實例包括SetResult, SetException, SetCanceled, 和它們的TrySet* 變量。

 

      你可以使用臨界區(Critical Section)、互斥量(Mutex)、信號量(Semaphores)和事件(Event)來處理線程同步。然而,在編寫一些異步處理函數,尤其是還有 async 和 await 使用的時候,還有一些更方便的類型可以用來處理線程同步。

使用 TaskCompletionSource ,你可以輕松地編寫既可以異步等待,又可以同步等待的代碼來。 

 

public class WalterlvDemo { private readonly TaskCompletionSource<object> _source = new TaskCompletionSource<object>(); public Task WaitAsync() => _source.Task; public void Wait() => _source.Task.GetAwaiter().GetResult(); }

var demo = new
WalterlvDemo();

等待時可以同步:  demo.Wait();

也可以異步:         await demo.WaitAsync();

而同步的那個方法,便可以用來做線程同步使用。

 

要像一個事件一樣讓同步等待阻塞着的線程繼續跑起來,則需要設置這個事件。

TaskCompletionSource<object> 提供了很多讓任務完成的方法: 

 

 

 可以通過讓這個 TaskCompletionSource<object> 完成、取消或設置異常的方式讓這個 Task 進入完成、取消或錯誤狀態,然后等待它的線程就會繼續執行;當然如果有異常,就會讓等待的線程收到一個需要處理的異常。

_source.SetResult(null);


免責聲明!

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



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