C#等待多线程完成(await与async)

17 篇文章 1 订阅
9 篇文章 0 订阅

C#优雅的完成多线程回调(await与async)

遇到的问题

我在写一个关于从资源服下载网络资源的代码时遇到一个问题,即我们无法在一个方法块中完成我们想要做的所有逻辑,如请求下载和资源加载完成逻辑。
我们通常的处理方式为:
调用资源下载接口,传递资源加载成功回调方法
当资源下载完成后,再去资源加载回调中去做资源处理。
当我们完成一个需求,需要下载多个资源时,回调方法将会越来越多。我们的代码也将越来越复杂。

将会产生如下的狗屎代码:
在这里插入图片描述
我们不能够直接得到文件,只能在此处请求资源下载,然后再将逻辑放到DownloadSuccess中,此时我们的代码的复杂度将会上升,如果文件存在七八上十个,那么对于文件下载完成的处理将非常复杂。如果我们需要拿到上面的文件之后,再去根据资源内容下载其他资源,那么将会出现更多的回调事件的嵌套。
我们能不能在请求网络下载的时候,直接获取到资源呢?
答案当然是不可以,我们虽然不能够同步获取到资源,但是我们想是否能够有别的办法在不阻塞主线程的情况下,使代码能够等待资源下载完成呢?
我发现,在C#的语法中有两个关键字:async与await。
我们可以使用await关键字等待async的代码(它在其他的子线程中)回调成功后,再做剩下的工作。

举例:
在这里插入图片描述
从这里看出,我们再Pick1中执行了子线程,调用者PickData直接将结果返回给了上级,上级的GetData1有一个await的操作。那么现在这个代码将会以什么顺序执行呢?

我们可以看到,只有在wait的后的代码才会在子线程中执行。
那么我们将代码改进之后。可以得到类似如下的代码
在这里插入图片描述
最后,我们发现线程ID,在执行子线程休息之后的代码都改变了当前线程的ID的。
那么在我们实际开发中,是不是就不能使用这个方式对UI进行更新操作呢?(一般子线程中是不允许对UI进行操作的,包括Unity3d中,也不允许对继承MonoBehaviour的类进行操作)
在这里插入图片描述
当时我想这个代码大概率会报错,不允许在子线程操作,如:
UnityException: get_isActiveAndEnabled can only be called from the main thread.

但实际上并没有发生这个报错,最后我们看一下在unity中的结果如何:
在这里插入图片描述
子线程运行确实是走到了子线程中,但是等到子线程运行结束的时候代码又回到的主线程。
这部分的原理我们通过调试发现应该是在Unity内部有进行一层封装,将消息传递回主线程中
在这里插入图片描述
在控制台中的程序堆栈为
在这里插入图片描述
具体的关于其原理我没有找到比较深入的资料。有兴趣的同学可以自行去网上学习~

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值