.NET 中使用 TaskCompletionSource 作爲線程同步互斥或異步操作的事件

 

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

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


 

本文內容

 

等待事件

我們創建一個 TaskCompletionSource<object> 對象,這樣,我們便可以寫出一個既可以同步等待又可以異步等待的方法:

public class WalterlvDemo
{
    private readonly TaskCompletionSource<object> _source = new TaskCompletionSource<object>();

    public Task WaitAsync() => _source.Task;

    public void Wait() => _source.Task.GetAwaiter().GetResult();
}

等待時可以同步:

demo.Wait();

也可以異步:

await demo.WaitAsync();

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

引發事件

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

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

TaskCompletionSource 中的方法

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

_source.SetResult(null);

我的博客會首發於 https://walterlv.com/,而 CSDN 和博客園僅從其中摘選發佈,而且一旦發佈了就不再更新。

知識共享許可協議

本作品採用知識共享署名-非商業性使用-相同方式共享 4.0 國際許可協議進行許可。歡迎轉載、使用、重新發布,但務必保留文章署名呂毅(包含鏈接:https://blog.csdn.net/wpwalter),不得用於商業目的,基於本文修改後的作品務必以相同的許可發佈。如有任何疑問,請與我聯繫

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