.NET - 实现"捕获所有异常处理程序"的最佳方法是什么

Tim*_*hyP 75 .net c# exception-handling exception

我想知道最好的方法是"如果所有其他方法都失败了".

我的意思是,你在应用程序中处理尽可能多的异常,但仍然存在bug,所以我需要有一些东西可以捕获所有未处理的异常,这样我就可以收集信息并将它们存储在数据库中或提交它们到网络服务.

AppDomain.CurrentDomain.UnhandledException事件是否捕获了所有内容?即使应用程序是多线程的?

旁注:Windows Vista公开了本机API函数,允许任何应用程序在崩溃后自行恢复...现在无法想到名称...但我宁愿不使用它,因为我们的许多用户仍在使用Windows XP.

boh*_*nko 33

我刚刚玩过AppDomain的UnhandledException行为,(这是未处理的异常注册的最后一个阶段)

是的,在处理事件处理程序后,您的应用程序将被终止,并显示令人讨厌的"...程序停止工作对话框".

:)你仍然可以避免这种情况.

查看:

class Program
{
    void Run()
    {
        AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

        Console.WriteLine("Press enter to exit.");

        do
        {
            (new Thread(delegate()
            {
                throw new ArgumentException("ha-ha");
            })).Start();

        } while (Console.ReadLine().Trim().ToLowerInvariant() == "x");


        Console.WriteLine("last good-bye");
    }

    int r = 0;

    void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        Interlocked.Increment(ref r);
        Console.WriteLine("handled. {0}", r);
        Console.WriteLine("Terminating " + e.IsTerminating.ToString());

        Thread.CurrentThread.IsBackground = true;
        Thread.CurrentThread.Name = "Dead thread";            

        while (true)
            Thread.Sleep(TimeSpan.FromHours(1));
        //Process.GetCurrentProcess().Kill();
    }

    static void Main(string[] args)
    {
        Console.WriteLine("...");
        (new Program()).Run();
    }
}
Run Code Online (Sandbox Code Playgroud)

PS处理更高级别的Application.ThreadException(WinForms)或DispatcherUnhandledException(WPF)的未处理.

  • 我想这是公平的,上面的代码让每个失败的线程永远存在.也就是说,你迟早会有大量的僵尸线.我个人认为没有那么有用. (20认同)
  • 这种解决方案是错误的,同时在某些情况下是如此必要:) +1 (3认同)
  • 我同意.那产生了僵尸.在悲伤中,我接受这个替代方案,在处理程序退出后立即终止我的应用程序.毕竟,在让死线永远休眠之前,您可以向服务器发送报告,让用户完成手头的任务并优雅地退出(或重新启动应用程序). (2认同)

ine*_*ine 16

在ASP.NET中,您可以使用文件中的Application_Error函数Global.asax.

在的WinForms,您使用MyApplication_UnhandledExceptionApplicationEvents的文件

如果代码中出现未处理的异常,则会调用这两个函数.您可以记录异常并从这些函数向用户显示一条好消息.


Bob*_*ler 13

对于Winform应用程序,除了AppDomain.CurrentDomain.UnhandledException之外,我还使用Application.ThreadExceptionApplication.SetUnhandledExceptionMode(w/UnhandledExceptionMode.CatchException).这种组合似乎抓住了一切.

  • 除了辅助线程,计时器线程和线程池线程上的异常之外的所有内容! (6认同)
  • 我同意,如果"处理异常"被理解为实际上要从中恢复,AppDomain的"UnhandledException"是不够的.但是,最初的问题似乎只针对错误报告而不是恢复.仅仅出于这个目的就足够了. (2认同)

Ste*_*owe 6

在主线程上,您有以下选项:

对于其他线程:

  • 辅助线程没有未处理的异常; 使用SafeThread
  • 工作者线程:(计时器,线程池)根本没有安全网!

请记住,这些事件不会处理异常,它们只会将它们报告给应用程序 - 通常是在对它们做任何有用/明智的事情为时已晚.

记录异常是好的,但监控应用程序更好;-)

警告:我是SafeThread文章的作者.