winform中的全局异常信息

本文介绍如何使用Application.ThreadException和AppDomain.CurrentDomain.UnhandledException事件来捕获和处理WinForms程序中的异常,包括UI线程和非UI线程的异常处理,并提供了解决方案防止程序因未处理异常而崩溃。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参考链接:

Application.ThreadException Event (System.Windows.Forms) | Microsoft Learn

由于作者水平有限,如有写得不对的地方请指正

捕获程序的全局异常信息是为了记录类似系统突然崩溃或者内存溢出等异常信息到日志中,方便后续查找问题

在我们公司的系统中,也可以看到类似的处理逻辑,如下图:

具体的注册事件方法就不能放出来了

1  记录UI线程的异常信息可以通过Application.ThreadException事件

2  记录非UI线程的异常信息可以通过AppDomain.CurrentDomain.UnhandledException事件

一    Application.ThreadException测试操作步骤如下:

1  新建winform程序,并拖拽一个button到窗体中,button的事件代码如下:

 private void button1_Click(object sender, EventArgs e)
 {
       throw new Exception("测试抛出异常");
 }

如果在程序中没有注册Application.ThreadException事件,点击button后,会出现如下图的异常信息:

弹出上述的提示信息,用户的体验极其不好,这样我们就需要捕获到这个异常信息并进行相应的处理,如记录日志并在合适的地方显示错误信息

 2  在winform的Program主方法中加入Application.ThreadException事件注册方法,代码如下:

static class Program
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.ThreadException += Application_ThreadException;
            Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }


        private static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
        {
            //1记录日志信息
            Exception ex = e.Exception;
            //2 弹出提示
            MessageBox.Show(string.Format("Application_ThreadException捕获到未处理异常:{0}\r\n异常信息:{1}\r\n异常堆栈:{2}", ex.GetType(), ex.Message, ex.StackTrace));
        }

    }

再次运行结果如下:

叉掉提示框后,程序正常运行

不过需要注意的是,当在界面渲染完毕前有异常信息,该事件就无效了,如把Program主方法的代码修改为:

[STAThread]
static void Main()
{
    Application.ThreadException += Application_ThreadException;
    Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
    bool flag = true;
    if (flag)
    {
        throw new Exception("主方法前加入测试异常信息抛出");
    }
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new Form1());
}

 运行后,发现,连界面都出不来了

二    AppDomain.CurrentDomain.UnhandledException事件测试步骤如下:

1  新建winform程序,并拖拽一个button到窗体中,button的事件代码如下:

private void button1_Click(object sender, EventArgs e)
{
   Thread thread = new Thread(()=> {
       throw new Exception("测试抛出异常");
   });
   thread.Start();
}

 2  编辑Program主方法的代码如下:

 static class Program
 {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }

        private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            //1 记录日志
            Exception ex = e.ExceptionObject as Exception;
            //2 弹出提示信息
            MessageBox.Show(string.Format("CurrentDomain_UnhandledException捕获到未处理异常:{0}\r\n异常信息:{1}\r\n异常堆栈:{2}", ex.GetType(), ex.Message, ex.StackTrace));
        }
    }

3  在方法CurrentDomain_UnhandledException入口打上断点并调试程序,弹出界面后,点击button按钮,调试结果如下:

可以看到,线程抛出异常后,就进入该事件方法了,如下图:

 

但叉掉提示框后,你可以发现,间大概3秒左右,程序直接退出了,所以可以猜测,当线程中如果有异常没有处理,则会导致程序崩溃退出,这样用户体验就很不好了。

好了,本文内容到此结束。

2023-06-17 日补充:

线程中未处理的异常导致程序崩溃退出的已找到解决方案,可以参考下面的博文

配置legacyUnhandledExceptionPolicy属性防止处理异常后程序崩溃退出(C#)_zxy2847225301的博客-优快云博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zxy2847225301

测试使用

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值