前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ThreadPool.QueueUserWorkItem引发的血案,线程池异步非正确姿势导致程序闪退的问题「建议收藏」

ThreadPool.QueueUserWorkItem引发的血案,线程池异步非正确姿势导致程序闪退的问题「建议收藏」

作者头像
全栈程序员站长
发布2022-09-07 11:43:17
8280
发布2022-09-07 11:43:17
举报
文章被收录于专栏:全栈程序员必看

大家好,又见面了,我是你们的朋友全栈君。

ThreadPool是.net System.Threading命名空间下的线程池对象。使用QueueUserWorkItem实现对异步委托的先进先出有序的回调。如果在回调的方法里面发生异常则应用程序会出现闪退。当然是指不处理那个异常的情况下。这不公司的CMS在生产环境频频出现闪退的情况。该死的是,原来用老机器配置不高的情况下没有出现过。换了更好的新机器后出现的。

代码语言:javascript
复制
        //
        // 摘要:
        //     将方法排入队列以便执行,并指定包含该方法所用数据的对象。此方法在有线程池线程变得可用时执行。
        //
        // 参数:
        //   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);

经过一番测试重新了故障现象,但由于是生产环境代码不好大动,看来解决方案就是吞掉异常,让程序不再闪退一种解决办法了。

编码测试过程

代码语言:javascript
复制
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引发的血案,线程池异步非正确姿势导致程序闪退的问题「建议收藏」
ThreadPool.QueueUserWorkItem引发的血案,线程池异步非正确姿势导致程序闪退的问题「建议收藏」

处理后

ThreadPool.QueueUserWorkItem引发的血案,线程池异步非正确姿势导致程序闪退的问题「建议收藏」
ThreadPool.QueueUserWorkItem引发的血案,线程池异步非正确姿势导致程序闪退的问题「建议收藏」

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/154820.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 编码测试过程
  • 处理前后对比
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档