首页 > 代码库 > ThreadPool.QueueUserWorkItem引发的血案,线程池异步非正确姿势导致程序闪退的问题
ThreadPool.QueueUserWorkItem引发的血案,线程池异步非正确姿势导致程序闪退的问题
ThreadPool是.net System.Threading命名空间下的线程池对象。使用QueueUserWorkItem实现对异步委托的先进先出有序的回调。如果在回调的方法里面发生异常则应用程序会出现闪退。当然是指不处理那个异常的情况下。这不公司的CMS在生产环境频频出现闪退的情况。该死的是,原来用老机器配置不高的情况下没有出现过。换了更好的新机器后出现的。
// // 摘要: // 将方法排入队列以便执行,并指定包含该方法所用数据的对象。此方法在有线程池线程变得可用时执行。 // // 参数: // callBack: // System.Threading.WaitCallback,它表示要执行的方法。 // // state: // 包含方法所用数据的对象。 // // 返回结果: // 如果此方法成功排队,则为 true;如果未能将该工作项排队,则引发 System.NotSupportedException。 // // 异常: // T:System.NotSupportedException: // 承载公共语言运行时 (CLR) 的宿主不支持此操作。 // // T:System.ArgumentNullException: // callBack 为 null。 [SecuritySafeCritical] public static bool QueueUserWorkItem(WaitCallback callBack, object state);
经过一番测试重新了故障现象,但由于是生产环境代码不好大动,看来解决方案就是吞掉异常,让程序不再闪退一种解决办法了。
编码测试过程
using System;using System.Threading;namespace ConsoleShell3{ //164-184 class Program { static object queueObj = new object(); static CoreThreadPool pool = new CoreThreadPool(); static void Main(string[] args) { Console.WriteLine("Main Thread OK..."); pool.Exceute += Pool_Exceute; pool.Start(); pool.Post(queueObj); Thread thread = new Thread(() => { while (true) { Thread.Sleep(1000); queueObj = (object)DateTime.Now.Ticks; Console.WriteLine(DateTime.Now); pool.Post(queueObj); } }); thread.Start(); Console.ReadLine(); } private static void Pool_Exceute(object obj) { ThreadPool.QueueUserWorkItem(CallbackDemoViod, obj); } /// <summary> /// 我的方案就是在这里把这个回调的方法用try catch包裹起来,吞到出现的异常 /// </summary> /// <param name="obj"></param> private static void CallbackDemoViod(object obj) { try { var inObj = obj; var ex = new Exception("!!!!"); throw ex; } catch (Exception ex) { Console.WriteLine(ex); } //以下不catch异常就会导致闪退 //var inObj = obj; //var ex = new Exception("!!!!"); //throw ex; } }}
处理前后对比
处理前
处理后
ThreadPool.QueueUserWorkItem引发的血案,线程池异步非正确姿势导致程序闪退的问题
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。