C# .NET-What';这是实施a";捕获所有异常处理程序“;
我想知道最好的办法是“如果其他方法都失败了,就抓住它” 我是说,你在应用程序中处理了尽可能多的异常, 但还是会有bug,所以我需要一些 捕获所有未处理的异常,以便我可以收集信息并存储 将它们保存在数据库中或提交给web服务 AppDomain.CurrentDomain.UnhandledException事件是否捕获所有内容? 即使应用程序是多线程的 旁注:Windows Vista公开允许任何应用程序使用的本机API函数 要在崩溃后恢复自己。。。现在想不起名字了。。。但我不想C# .NET-What';这是实施a";捕获所有异常处理程序“;,c#,.net,exception,exception-handling,C#,.net,Exception,Exception Handling,我想知道最好的办法是“如果其他方法都失败了,就抓住它” 我是说,你在应用程序中处理了尽可能多的异常, 但还是会有bug,所以我需要一些 捕获所有未处理的异常,以便我可以收集信息并存储 将它们保存在数据库中或提交给web服务 AppDomain.CurrentDomain.UnhandledException事件是否捕获所有内容? 即使应用程序是多线程的 旁注:Windows Vista公开允许任何应用程序使用的本机API函数 要在崩溃后恢复自己。。。现在想不起名字了。。。但我不想 使用它,因为我
使用它,因为我们的许多用户仍在使用Windows XP。在ASP.NET中,您可以使用
Global.asax
文件中的Application\u Error
函数
在WinForms中,使用ApplicationEvents
文件中的MyApplication\u UnhandledException
如果代码中发生未处理的异常,则会调用这两个函数。您可以记录异常并通过这些函数向用户显示一条好消息。对于WinForms,也不要忘记附加到当前线程的未处理异常事件(尤其是在使用多线程时)
除了AppDomain.CurrentDomain.UnhandledException,我还使用和(w/UnhandledExceptionMode.CatchException),Winform应用程序的最佳实践和和的一些链接。此组合似乎可以捕获所有内容。在主线程上,您有以下选项:
- 控制台或服务应用程序:
- WinForms应用程序:
- Web应用程序:全局.asax的
application\u错误
- 次线程没有未处理的异常;使用
- 工作线程:(计时器,线程池)根本没有安全网李>
警告:我是这篇文章的作者。还有一个很酷的东西,它将记录web应用程序中发生的任何ASP.NET错误。我知道您正在询问Winform应用程序解决方案,但我觉得这对任何需要在web应用程序上使用此类功能的人都是有益的。我们在我工作的地方使用它,它对调试非常有帮助(特别是在生产服务器上!) 以下是它的一些功能(从页面上直接删除):
- 记录几乎所有未处理的异常
- 远程查看重新编码异常的整个日志的网页
- 远程查看任何一个已记录异常的完整详细信息的网页
- 在许多情况下,你可以回顾最初的死亡黄屏 为给定对象生成的ASP.NET 异常,即使在customErrors模式下也是如此 关掉
- 每个错误发生时的电子邮件通知
- 日志中最近15个错误的RSS提要
- 日志的许多备份存储实现,包括 在内存中,Microsoft SQL Server和 社区贡献了一些资源
即使在多线程应用程序中,您也可以监视该处理程序中的大多数异常,但是.NET(从2.0开始)不允许您取消未处理的异常,除非您启用1.1兼容模式。当这种情况发生时,AppDomain将被关闭。最好是在不同的AppDomain中启动应用程序,以便处理此异常并创建新的AppDomain以重新启动应用程序 我正在使用下面的方法,这种方法很有效,并且大大减少了代码量(但我不确定是否有更好的方法,或者它可能存在什么陷阱)。 无论何时打电话: 我想问的是,提问者给出错误的答案会有礼貌地澄清他们的行为;) 下面是ErrorHandler代码: 只是想弄清楚-:objUser-是为应用程序用户建模的对象(您可能会获得域名、部门、地区等信息,以便进行日志记录) ILog logger-是日志记录对象-例如,执行日志记录活动的对象 StackTrace st-StackTrace对象为您提供应用程序的调试信息
using System;
using log4net; //or another logging platform
namespace GenApp.Utils
{
public class ErrorHandler
{
public static void Trap ( Bo.User objUser, ILog logger, System.Diagnostics.StackTrace st, Exception ex )
{
if (ex is NullReferenceException)
{
//do stuff for this ex type
} //eof if
if (ex is System.InvalidOperationException)
{
//do stuff for this ex type
} //eof if
if (ex is System.IndexOutOfRangeException)
{
//do stuff for this ex type
} //eof if
if (ex is System.Data.SqlClient.SqlException)
{
//do stuff for this ex type
} //eof if
if (ex is System.FormatException)
{
//do stuff for this ex type
} //eof if
if (ex is Exception)
{
//do stuff for this ex type
} //eof catch
} //eof method
}//eof class
} //eof namesp
我刚刚玩过AppDomain未处理的异常行为, (这是注册未处理异常的最后一个阶段) 是的,在处理事件处理程序后,您的应用程序将被终止,并显示令人讨厌的“…程序停止工作”对话框 :) 你还是可以避免的 退房:
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();
}
}
p.S.在更高级别上处理Application.ThreadException(WinForms)或DispatcherUnhandleException(WPF)的未处理异常。在受管理的GUI应用程序中,默认情况下,GUI线程中产生的异常由分配给Application.ThreadException的任何对象处理 源自其他线程的异常由AppDomain.CurrentDomain.UnhandledException处理 如果希望GUI线程异常与非GUI线程异常一样工作,以便由AppDomain.CurrentDomain.UnhandledException处理它们,可以执行以下操作:
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException);
使用ThreadException捕获GUI线程异常的一个优点是,您可以为用户提供让应用程序继续的选项。要确保没有配置文件覆盖默认行为,可以调用:
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
您仍然容易受到行为不良的本机DLL的异常的攻击。如果本机dll使用Win32 SetUnhandledExceptionFilter安装自己的处理程序,则应该保存指向上一个筛选器的指针并调用它。如果它不这样做,您的处理程序将不会被调用。请链接到“当前线程的未处理异常事件”的引用,我当时处于
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);