C# 同步轉異步 AutoResetEvent


當我們的程序運行時,調用了一段異步的邏輯A,這段異步的邏輯無法轉化為同步(如動畫、下載進度等)

而,我們又需要等待異步邏輯A處理完成,然后再執行其它邏輯B。

AutoResetEvent 同步轉異步

AutoResetEvent autoResetEvent = new AutoResetEvent(false)

AutoResetEvent 可以在線程間發送信號互相通信,通過調用 AWaitOne 來等待信號,調用Set發送信息來啟動已等待的線程。

很簡單:一個await ,另一個set來喚醒。

  1. AutoResetEvent autoResetEvent = new AutoResetEvent(false)--參數bool:若要將初始狀態設置為終止,則為 true;若要將初始狀態設置為非終止,則為 false
  2. await Task.Run(() => { autoResetEvent.WaitOne(); });
  3. 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的確可以由同步轉成異步方法,但是以上方案是創建了一個新的任務,如果是大量的處理會有性能問題~

關鍵字:動畫同步,AutoResetEvent

 


免責聲明!

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



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