并发系列64章(异步编程三)第四章

前言

续写第三章,结束掉一些例子。

避免上下文延续

这是什么意思呢?

是这样的,在默认情况下,一个async 方法在被await调用恢复的时候呢,会在原来的上下文中运行。

啥上下文?那么什么是上下文呢?在我们以前做语文的时候,请参考上下文然后怎么怎么的。

这个上下文,其实就是状态。比如说我看一篇文章,看到了第三句,说的是"他轻轻的走了"。那么这个他是谁?

那么我们结合第一句,"远远的他来了,往近一瞅,他是小明。" 那么他就是小明。前面的上下文就是状态。

每一个async都是一篇文章,都有上下文状态,当切换await的时候,还有继续往下看,那么就要切换上下文。

那么async 这个状态是啥?

从使用async修饰符修饰的方法的IL代码可以得出一个结论:

在Debug下,针对async方法,生成的是一个class状态机

在Release下,针对async方法,生成的是一个struct状态机

这个上下文就是状态机。

那么这个状态机是啥?为了避免我写第五章还是异步编程,在此只做简单介绍。

1.每个async 都有一个状态机,状态机控制着async方法的运行。

2.状态机的状态为:-1:初始化;-2:方法体执行结束;1:第一个await;2:第二个await是否完成。

具体这个状态机丢弃了,有什么副作用呢?

请用ILSpy 反编译查看,涉及到原理。

我在后续中,我会写一章反编译来解释await 和 async 的原理,仅仅是个人理解。

处理async void 方法的异常

首先说一下为什么不推荐使用async 返回void呢?

这就有一个问题,如果我们做地铁的时候,总部不知道地铁跑到哪里了,这是否是一个问题?因为不返回task,那么到底啥情况呢?

但是void 有必须存在,例如命令式的异步事件,因为没有返回task意义何在。

什么是命令式的?

比如说winfrom的异步事件,我点击了一个按钮。

这种就是命令式的。我只是触发了点击按钮这个事件,这个事件调用我们的程序。至于点击之后发生什么,没有必要知道。

那么如何测试async void 呢?

请参考:
https://docs.microsoft.com/zh-cn/archive/msdn-magazine/2014/november/async-programming-unit-testing-asynchronous-code#避免-async-void-单元测试

这里面介绍了,我就不啰嗦了。

结尾

下一章 并行编程。

posted @ 2020-04-09 17:34  敖毛毛  阅读(182)  评论(0编辑  收藏  举报