优秀的编程知识分享平台

网站首页 > 技术文章 正文

C# Winform 中统一处理未捕获的异常信息

nanyue 2025-01-29 17:20:02 技术文章 102 ℃

在给客户演示软件功能时,你精心编写的 WinForms 桌面应用程序运行得好好的,突然抛出一个未捕获的异常,用户面前弹出一个吓人的错误窗口,然后就莫名其妙地关闭了,毫无预警。

这不仅让用户感到困惑,也让作为开发者的你感到无比尴尬。为了防止这种情况的发生,我们需要在 WinForms 中设置一个全局的异常处理机制。

今天,我们来看看如何为你的 WinForms 桌面应用程序穿上一件“防护服”,让它能够优雅地处理这些未捕获的异常,提升程序的稳定性和用户体验。

1. 创建一个新的 WinForms 项目,命名为“ExceptionHandlerDemo”

2. 添加一个简单的用户界面

  • 在设计视图中,拖一个 Button 控件到默认的 Form1 窗体上。
  • 将按钮的 Text 属性设置为“抛出异常”。

3. 添加引发异常的代码

在按钮的 Click 事件中,我们故意抛出一个异常。

private?void?button1_Click(object?sender, EventArgs e)
{
? ??throw?new?InvalidOperationException("这是一个测试异常!");
}

4. 订阅全局异常事件

设置全局异常处理机制来获未处理的异常,可以通过订阅 Application.ThreadExceptionAppDomain.CurrentDomain.UnhandledException 事件来实现。

这就像告诉应用程序:“嘿,如果你遇到任何未捕获的异常,请不要慌,我会帮你处理的。”

Program.cs 文件中编写以下代码:

internal?static?class?Program
{
? ??///?
? ??///? 应用程序入口
? ??///?
? ? [STAThread]
? ??static?void?Main()
? ? {
? ? ? ? ApplicationConfiguration.Initialize();

? ? ? ??// 订阅 ThreadException 事件,用于捕获 UI 线程上的未捕获异常
? ? ? ? Application.ThreadException +=?new?ThreadExceptionEventHandler(Application_ThreadException);

? ? ? ??// 设置未经处理的异常模式,以便在非 UI 线程上也能捕获异常
? ? ? ? Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);

? ? ? ??// 订阅 UnhandledException 事件,用于捕获所有线程上的未捕获异常
? ? ? ? AppDomain.CurrentDomain.UnhandledException +=?new?UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

? ? ? ? Application.Run(new?Form1());
? ? }

? ??// 处理 UI 线程上的未捕获异常
? ??private?static?void?Application_ThreadException(object?sender, ThreadExceptionEventArgs e)
? ? {
? ? ? ? HandleException(e.Exception);
? ? }

? ??// 处理所有线程上的未捕获异常
? ??private?static?void?CurrentDomain_UnhandledException(object?sender, UnhandledExceptionEventArgs e)
? ? {
? ? ? ? HandleException(e.ExceptionObject?as?Exception);
? ? }

? ??// 统一的异常处理方法
? ??private?static?void?HandleException(Exception ex)
? ? {
? ? ? ??if?(ex ==?null)?return;

? ? ? ??// 记录错误日志

? ? ? ??// 显示友好的错误信息给用户
? ? ? ? MessageBox.Show(@$"
对不起,应用程序遇到了一个问题,错误信息如下:
{ex.Message}

我们已经记录了这个问题,稍后会进行修复。",
? ? ? ? ? ? ? ? ? ? ? ??"应用程序错误", MessageBoxButtons.OK, MessageBoxIcon.Error);

? ? ? ??// (可选)退出应用程序或采取其他措施
? ? ? ? Application.Exit();
? ? }
}

5. 测试代码

按 Ctrl+F5 编译并运行程序,然后点击按钮引发异常,你应该会看到一个友好的错误提示框,显示捕获到的异常信息,如下图:

总结

想象一下,你正在开车,突然遇到了一个坑洼,如果你事先知道这一点,提前减速或绕道行驶,是不是会更安全、更舒适?

同样,在编程中,如果我们能提前为应用程序设置好应对策略,就可以更好地保护它免受意外的伤害。

通过在 WinForms 应用程序中设置全局异常处理器,我们就可以捕获并优雅地处理所有未被捕获的异常,无论是 UI 线程还是其他线程的异常,避免那些令人头疼的崩溃,提升用户体验。

最近发表
标签列表