你可以使用臨界區(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<object>
完成、取消或設置異常的方式讓這個 Task 進入完成、取消或錯誤狀態,然後等待它的線程就會繼續執行;當然如果有異常,就會讓等待的線程收到一個需要處理的異常。
_source.SetResult(null);
我的博客會首發於 https://walterlv.com/,而 CSDN 和博客園僅從其中摘選發佈,而且一旦發佈了就不再更新。
本作品採用知識共享署名-非商業性使用-相同方式共享 4.0 國際許可協議進行許可。歡迎轉載、使用、重新發布,但務必保留文章署名呂毅(包含鏈接:https://blog.csdn.net/wpwalter),不得用於商業目的,基於本文修改後的作品務必以相同的許可發佈。如有任何疑問,請與我聯繫。