C#~异步编程再续~你必须要知道的ThreadPool里的throw
原创
©著作权归作者所有:来自51CTO博客作者仓储大叔的原创作品,请联系作者获取转载授权,否则将追究法律责任
问题依旧存在
之前写过相关文章异步编程的文章,本文主要还是一点补充,之前在IIS经常发w3wp进程无做挂了的情况,但一直没能找到真正的原因,而查找相关资料,找了一些相关的文章,如await和async引起的线程死锁,也都进行了分析,但和我们项目的情况有些不同,因为在我们项目里只用了ThreadPool和Task.Run这种线程池,而异步用了也是异步到底的!
今天无意中看到一个文章,说到了在ThreadPool中如果出现异常,并且你没有捕捉它,直接throw了,这时也会引用w3wp进程的死掉,我在电脑上试了一下,确实有这种情况,于是很兴奋!
在事件查看器里的截图
最后将我的线程池方法进行了改良,解决了这个问题
优化后的代码
/// <summary>
/// 线程管理
/// </summary>
public class ThreadManager
{
/// <summary>
/// 将在线程池上运行的指定工作排队
/// </summary>
/// <param name="action"></param>
public static void Run(Action action)
{
ThreadPool.QueueUserWorkItem(u =>
{
try
{
action();
}
catch (Exception ex)
{
Lind.DDD.Logger.LoggerFactory.Instance.Logger_Error(ex);
}
});
}
}
下面我自己做了一个测试,在.net里的4种开启新线程的方式,及它们是否会引起w3wp服务挂掉,做了一个对比,请看代码
//w3wp会有挂机问题
{
var b = 0;
var c = 1 / b;
});
Task.Run(() => //不会有挂机问题
{
var b = 0;
var c = 1 / b;
});
new Thread(() =>//w3wp会有挂机问题
{
var b = 0;
var c = 1 / b;
}).Start();
Task.Factory.StartNew(() =>//不会有挂机问题
{
var b = 0;
var c = 1 / b;
});
最后,很高兴找到又一个引起w3wp进程挂掉的原因,希望这次可以真正解决这个问题!
作者:仓储大叔,张占岭,
荣誉:微软MVP