當我們的程式運作時,調用了一段異步的邏輯A,這段異步的邏輯無法轉化為同步(如動畫、下載下傳進度等)
而,我們又需要等待異步邏輯A處理完成,然後再執行其它邏輯B。
那就迫切需要将異步轉同步了!
AutoResetEvent autoResetEvent = new AutoResetEvent(false)
AutoResetEvent 可以線上程間發送信号互相通信,通過調用 AWaitOne 來等待信号,調用Set發送資訊來啟動已等待的線程。
很簡單:一個await ,另一個set來喚醒。
- AutoResetEvent autoResetEvent = new AutoResetEvent(false)--參數bool:若要将初始狀态設定為終止,則為 true;若要将初始狀态設定為非終止,則為 false
- await Task.Run(() => { autoResetEvent.WaitOne(); });
- autoResetEvent.Set();
比如:
private async Task SetDelegateProgress()
{
var delegateProgress = new UIDelegateProgress();
delegateProgress.ProgressCompleted += () =>
{
autoResetEvent.Set();
};
DelegateProgress = delegateProgress;
await Task.Run(() => { autoResetEvent.WaitOne(); });
}
如上案例,當delegateProgress執行完後,通過AutoResetEvent 的方法Set來發送資訊來喚醒子線程。
再如動畫的同步等待處理:
1 /// <summary>
2 /// 執行動畫
3 /// </summary>
4 /// <param name="storyboard"></param>
5 /// <returns></returns>
6 public static async Task ExecuteStoryboradAsync([NotNull] Storyboard storyboard)
7 {
8 if (storyboard == null) throw new ArgumentNullException(nameof(storyboard));
9
10 AutoResetEvent autoResetEvent = new AutoResetEvent(false);
11
12 storyboard.Completed += OnStoryboardCompleted;
13 storyboard.Begin();
14
15 void OnStoryboardCompleted(object sender, EventArgs e)
16 {
17 storyboard.Completed -= OnStoryboardCompleted;
18 autoResetEvent.Set();
19 }
20
21 await Task.Run(() => { autoResetEvent.WaitOne(); });
22 }
值得注意的是,WaitOne隻能在子線程,如果放在主線程的話,會将整個線程終止(例如界面或者其它背景邏輯)
AutoResetEvent 可以在多個線程使用WaitOne來暫停線程,而暫停的線程則需要多次set來開啟暫停的線程。
給你AutoResetEvent 類似的,還有一個ManualResetEvent。ManualResetEvent 是多個暫停線程,可以通過一次set直接開啟全部暫停的線程。
ManualResetEvent與AutoResetEvent 不同的還有Reset方法,Reset與Set相反,為主動暫停線程。
詳細ManualResetEvent & AutoResetEvent可參考:
https://www.cnblogs.com/maitian-lf/p/3672390.html關鍵字:動畫同步,AutoResetEvent
作者:
唐宋元明清2188出處:
http://www.cnblogs.com/kybs0/本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須在文章頁面給出原文連接配接,否則保留追究法律責任的權利。