我想知道最好的方法是"如果所有其他方法都失败了".
我的意思是,你在应用程序中处理尽可能多的异常,但仍然存在bug,所以我需要有一些东西可以捕获所有未处理的异常,这样我就可以收集信息并将它们存储在数据库中或提交它们到网络服务.
AppDomain.CurrentDomain.UnhandledException事件是否捕获了所有内容?即使应用程序是多线程的?
旁注:Windows Vista公开了本机API函数,允许任何应用程序在崩溃后自行恢复...现在无法想到名称...但我宁愿不使用它,因为我们的许多用户仍在使用Windows XP.
我刚刚玩过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(); } }
PS处理更高级别的Application.ThreadException(WinForms)或DispatcherUnhandledException(WPF)的未处理.
在ASP.NET中,您可以使用文件中的Application_Error
函数Global.asax
.
在的WinForms,您使用MyApplication_UnhandledException
中ApplicationEvents
的文件
如果代码中出现未处理的异常,则会调用这两个函数.您可以记录异常并从这些函数向用户显示一条好消息.
对于Winform应用程序,除了AppDomain.CurrentDomain.UnhandledException之外,我还使用Application.ThreadException和Application.SetUnhandledExceptionMode(w/UnhandledExceptionMode.CatchException).这种组合似乎抓住了一切.
在主线程上,您有以下选项:
控制台或服务应用: AppDomain.CurrentDomain.UnhandledException
WinForms应用程序: Application.ThreadException
Web应用程序:Global.asax Application_Error
对于其他线程:
辅助线程没有未处理的异常; 使用SafeThread
工作者线程:(计时器,线程池)根本没有安全网!
请记住,这些事件不会处理异常,它们只会将它们报告给应用程序 - 通常是在对它们做任何有用/明智的事情为时已晚.
记录异常是好的,但监控应用程序更好;-)
警告:我是SafeThread文章的作者.