最近怪事又开始发生了,IIS的应用程序池无做挂掉,都指向同一个矛头,async,threadPool,Task,还有一个System.NullReferenceException,所以这些都让我们感觉,我们的异步程序出现了问题,事实也是如此,我们的异步调用引用了对“上下文”的非空引用,最后导致w3wp进程死掉!
通过其它前辈的分享,找到了问题产生的原因,大叔也总结一下
1 async方法需要使用await等待它的结果,这样可以保证你的SynchronizationContext上下文不为空,即不会出现非空引用的错误。
2 在调用async方法时,如果不方法加await关键字,也可以使用它的ConfigureAwait( false )方法,它虽然不会保存SynchronizationContext上下文,但它也不会报非空引用的错误。
3 在一个新线程里调用async的异步方法,需要我们注意上面两点
参看文章
http://www.cnblogs.com/cmt/p/configure_await_false.html
http://www.cnblogs.com/cmt/p/sokcet_memory_leak.html
技术点说明
1 Task.Run(()=>{}); 将一个任务添加到线程池里,排队执行
2 async 标识一个方法为异步方法,可以与主线程并行执行,发挥CPU的多核优势
3 await 在调用一个async方法前可以添加这个修饰符,它意思是等待当前异步方法执行完后,再执行下面的代码
4 ConfigureAwait(true),代码由同步执行进入异步执行时,当前线程上下文信息就会被捕获并保存至 SynchronizationContext中,供异步执行中使用,并且供异步执行完成之后的同步执行中使用
5 Configurewait(flase),不进行线程上下文信息的捕获,async方法中与await之后的代码执行时就无法获取await之前的线程的上下文信息,在ASP.NET中最直接的影响就是HttpConext.Current的值为null,但不会出现非空引用的错误
以上就是我们在解决由异步引起的w3wp.exe崩溃中所学习到的知识!
感谢各位的阅读!