最近在学习.net framwork的异步,看了很多博客,也学习了很多,不过在MSDN上关于在UI上await造成的死锁不是很理解,经过今天上午的思考,才感觉自己被单线程的执行流程局限了,当然也记录下来我自己的思考过程
首先贴一下MSDN的文章地址
https://msdn.microsoft.com/zh-cn/magazine/hh456402.aspx
以及我之前疑问的代码段
下面是关于这块逻辑的理解的流程图
流程解释
首先按钮的onlick事件触发,之后第一步执行的是UI的主线程,之后到达 CopyStreamToStreamAsync方法,
CopyStreamToStreamAsync方法体
在这之前都是同步线程,之后CopyStreamToStreamAsync由于异步的原因,开始进行异步执行,主线程继续执行,直到t.waiit()方法,主线程被阻塞,这个时候异步方法并没有忽略UI线程的上下文,到达方法体的await方法时,异步的执行规则是要
捕获上下文,也就是要回到UI主线程中,恰恰这个时候主线程被阻塞了,而wait()方法本身是等待Task任务执行完毕后再执行的,这个时候就会导致,双方无条件的等待彼此结束,而造成死锁
MSDN上的解决方案是忽略UI的上下文,这样让任务运行在线程池的上下文中来避免死锁