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

ThreadPool.QueueUserWorkItem引发的血案,线程池异步非正确姿势导致程序闪退的问题「建议收藏」ThreadPool是.net System.Threading命名空间下的线程池对象。使用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引发的血案,线程池异步非正确姿势导致程序闪退的问题「建议收藏」

处理后

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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

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

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • pytorch安装-国内镜像源

    pytorch安装-国内镜像源在安装好cuda和cudnn之后安装pytorch的方法网上很多的方法都不是镜像下载,或者镜像下载因为系统的问题找不到库打开官网,找到对应合适的版本(cuda):https://pytorch.org/get-started/locally/之后复制下面这一行指令:condainstallpytorchtorchvisiontorchaudiocudatoolkit=11.0-cpytorch接下来就是关键一步了,把-cpytorch表示的pytorch源,更改为国内的镜像。

    2022年6月24日
    58
  • 利用MDK软件生成bin文件的简单方法

    利用MDK软件生成bin文件的简单方法一、缘由:之前学习KeilMDK-ARM软件,找了好久生成bin文件的方法,这次分享最简单的,所以写了此篇博文二、操作步骤:1、打开“KeilMDK-ARM软件”-找到魔术棒“Optionsfortarget…”:2、点击“User”选择AfterBulid/Rebuild状态下的“▢Run#1”:3、点击后面的空白处,写入命令,,最后关闭窗口,重新编译软件,即可生成bin文件:4、具体命令如下:命令格式1:fromelf.exe–bin-o“%L@L.

    2022年10月20日
    2
  • keil调试程序的断点设置技巧

    keil调试程序的断点设置技巧这几天整同事留下来的项目的BOM,很简单的错误,弄的头大,看下文章分下神,值得尝试一下这个调试方法。程序运行过程中,有些数据被莫名修改了,在哪里修改的?又是怎么修改的?这个代码我只想知道是否运行过,或者运行了多少次,但是不想让程序停下来,或者仅打印调试信息,怎么办?当这个变量设置成某个数据后,我想让程序自动暂停下来进行分析,怎么办?以上问题的所有答案就在本节内容:断点窗口(KEIL)。本节…

    2025年6月1日
    2
  • 时间片轮转调度算法详解

    时间片轮转调度算法详解轮转调度算法 Round Robin RR 在分时系统中都采用时间片轮转算法进行进程调度 时间片是指一个较小的时间间隔 通常为 10 100 毫秒 在简单的轮转算法中 系统将所有的就绪进程按先来先服务 即 FIFO 规则排成一个队列 将 CPU 分配给队首进程 且规定每个进程最多允许运行一个时间片 若时间片使用完进程还没有结束 则被加入就绪 FIFO 队列队尾 并把 CPU 交给下一个进程 时间片轮转算法只用于进程调度 它属于抢占调度方式 优点 CPU 分配相对公平 平均响应时间较短缺点 不利于紧急作业 而且当进程

    2025年8月18日
    2
  • 《经济学人》深度报道:DeepMind和谷歌的AI拉锯战

    《经济学人》深度报道:DeepMind和谷歌的AI拉锯战

    2021年7月3日
    194
  • 【转】使用Chrome Frame,彻底解决浏览器兼容问题「建议收藏」

    【转】使用Chrome Frame,彻底解决浏览器兼容问题「建议收藏」本文转自http://www.ryanbay.com/?p=269,感谢该作者的总结 X-UA-Compatible是自从IE8新加的一个设置,对于IE8以下的浏览器是不识别的。通过在meta中设置X-UA-Compatible的值,可以指定网页的兼容性模式设置。在网页中指定的模式优先权高于服务器中(通过HTTPHeader)所指定的模式。兼容性模式设置优先级: metatag&gt;…

    2022年7月16日
    29

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号