免费手机网站源码,seo教程从零开始,wordpress自带企业主题下载,哪些浏览器可以看禁止访问的网站小明用async/await写了几年的异步方法#xff0c;但总没有完全理解里面的机制#xff0c;他决定去请教邻居小花。小花听了小明的描述后说#xff1a;首先你要明白异步的根本是什么#xff1f;大白话解释异步就是#xff1a;拉一个人#xff08;线程#xff09;帮着做一些… 小明用async/await写了几年的异步方法但总没有完全理解里面的机制他决定去请教邻居小花。小花听了小明的描述后说首先你要明白异步的根本是什么大白话解释异步就是拉一个人线程帮着做一些耗时的事下载、读写数据库等,自己先做别的事了退出线程,等做好了和我说下我再继续做后面的事恢复上下文。小花看到小明还没有听明白就说我举个简单例子帮你理解吧假如有两个方法A和BA调用B方法B方法是一个异步方法这时A不等待B执行完如图现在两个方法被分隔几个小块await关键字其实就用来隔开同步和异步上面的方法执行流程如下A调用B方法后B方法在未执行到await之前还是同步方法比如输出Sub1还是在当前线程中执行当方法遇到await后就会把await后的方法放到新的线程中执行当前线程则退出函数由于调用的地方并没有await则主线程会继续执行并输出Part2然后结束。等新线程中Thread.Sleep(5000)执行完后会执行到Console.Write(Sub2);这一行代码会回到原来的线程执行其实调用线程在遇到await时会捕获当前线程的执行上下文然后给到新线程新线程在执行完耗时操作后会判断之前捕获到的执行上下方是否为null如果不为null则会在上下文中恢复并执行后面的方法其实就是通过Tak的ContineWith方法注册回调如图小明好像听懂了一些说现在A方法调用DoSomethingAsync()并没有等待如果A方法需要这个方法执行完才能继续执行是不是要在DoSomethingAsync()前面加上await小花回答是并说方法只要遇到await就会把后面的方法给新线程执行然后退出线程去执行别的方法等新线程执行完后再通知当前线程恢复上下文继续执行如图小明又问你说异步方法执行完后后面的方法会在原来的线程中恢复并执行如果我还想在新线程中继续执行剩下的代码要怎么办呢小花说问的好await调用新线程执行耗时操作时默认会捕获当前上下文如果不想捕获则可以调用ConfigAwait(false)方法如图执行流程如下小花补充到上线提到的线程1、线程2、线程3等不一定准确因为异步的回调使用的是线程池中的线程所以回调有可能还在原来线程中执行这个主要看操作系统的调度。小明满意地点点头又问我经常听同事说用异步方法会死锁这又是为什么呢小花听了说他们肯定是在调用异步方法的时候使用.Result()如图小花指着图解释说上面的代码task.Result()会阻塞线程并等待task返回结果DoSomethingAsync方法在执行完Thread.Sleep(5000)后发现捕获到的上下文不为空则会尝试将Console.Write(Sub2)这行代码交由调用线程去执行而这时调用线程还在阻塞等待就这样互相卡着对方从而造成了死锁如图小明点了点头又问那要怎么避免呢小花说出现这种情况也和框架有关像WinForm为了让所有UI操作都在主线程中执行就添加了一个SynchronizationContext类实例用以表示当前上下文而像控制台等项目这个SynchronizationContext实例默认为null所以即使使用.Result也不会死锁。但最好使用异步的时候不要用.Result可以使用ConfigAwait(false)指明不捕获上下文或所有的方法全部异步到底。小明听完拜别了小花回到了自己的隔间。