• 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

  • 相关阅读:
    嵌入式系统编程和调试技巧
    使用Kotlin开发Android应用(II):创建新project
    2015 Multi-University Training Contest 2
    C#开发Unity游戏教程之游戏对象的属性变量
    Java开发project师案例-网络日志分析系统
    Flask
    Flask
    Flask
    Flask
    Flask
  • 原文地址:https://www.cnblogs.com/kybs0/p/8468464.html
Copyright © 2020-2023  润新知