C# 异步转同步

简介: 当我们的程序运行时,调用了一段异步的逻辑A,这段异步的逻辑无法转化为同步(如动画、下载进度等) 而,我们又需要等待异步逻辑A处理完成,然后再执行其它逻辑B。 那就迫切需要将异步转同步了! AutoResetEvent autoResetEvent = new AutoResetEvent(false) AutoResetEvent 可以在线程间发送信号互相通信,通过调用 AWaitOne 来等待信号,调用Set发送信息来启动已等待的线程。

当我们的程序运行时,调用了一段异步的逻辑A,这段异步的逻辑无法转化为同步(如动画、下载进度等)

而,我们又需要等待异步逻辑A处理完成,然后再执行其它逻辑B。

那就迫切需要将异步转同步了!

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

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面给出原文连接,否则保留追究法律责任的权利。
目录
相关文章
|
3月前
|
编译器 数据处理 C#
C#中的异步流:使用IAsyncEnumerable<T>和await foreach实现异步数据迭代
【1月更文挑战第10天】本文介绍了C#中异步流的概念,并通过使用IAsyncEnumerable<T>接口和await foreach语句,详细阐述了如何异步地迭代数据流。异步流为处理大量数据或需要流式处理数据的场景提供了一种高效且非阻塞性的方法,使得开发者能够更优雅地处理并发和数据流问题。
|
5天前
|
C#
C# async await 异步执行方法
C# async await 异步执行方法
9 0
|
2月前
|
C#
蓝易云 - C#将异步改成同步方法
注意:虽然这样可以将异步方法转为同步,但在实际开发中,我们通常推荐使用异步方法,因为它可以提高应用程序的响应性和并发性。将异步方法转为同步可能会导致死锁或性能问题。
20 2
|
3月前
|
C#
C#同步异步详解
C#同步异步详解
25 0
|
12月前
|
C# 开发者
C# 开发者技术:进程间数据共享之管道(Pipes)-异步通信版
主要类 1.NamedPipeClientStream 2.NamedPipeServerStream 解释:命名管道是一种进程间通信的方式,它允许不同进程之间在同一台机器上进行通信
680 2
C# 开发者技术:进程间数据共享之管道(Pipes)-异步通信版
|
9月前
|
C#
C#异步详解
c#异步编程原理,await asnyc的使用方法
48 0
|
安全 算法 机器人
Baumer工业相机堡盟工业相机如何使用BGAPISDK对两个万兆网相机进行触发同步(C#)
Baumer工业相机堡盟工业相机如何使用BGAPISDK对两个万兆网相机进行触发同步(C#)
97 0
Baumer工业相机堡盟工业相机如何使用BGAPISDK对两个万兆网相机进行触发同步(C#)
|
存储 编解码 算法
Baumer工业相机堡盟工业相机如何通过BGAPISDK的软触发实现两相机的同步采集(C#)
Baumer工业相机堡盟工业相机如何通过BGAPISDK的软触发实现两相机的同步采集(C#)
111 0
|
存储 前端开发 API
C# 从做早餐看同步异步
C# 从做早餐看同步异步
48 0
|
存储 SQL 设计模式
C#异步有多少种实现方式?
C#异步有多少种实现方式?