首页 > 代码库 > 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引发的血案,线程池异步非正确姿势导致程序闪退的问题