到目前为止,我只是在程序Application.Run
的Program.cs
入口点周围放置了一个 try/catch 块。这在调试模式下可以很好地捕获所有异常,但是当我在没有调试模式的情况下运行程序时,不再处理异常。我得到未处理的异常框。
我不希望这种情况发生。我希望在非调试模式下运行时捕获所有异常。该程序有多个线程,最好是它们的所有异常都被同一个处理程序捕获;我想在数据库中记录异常。有人对如何做到这一点有任何建议吗?
到目前为止,我只是在程序Application.Run
的Program.cs
入口点周围放置了一个 try/catch 块。这在调试模式下可以很好地捕获所有异常,但是当我在没有调试模式的情况下运行程序时,不再处理异常。我得到未处理的异常框。
我不希望这种情况发生。我希望在非调试模式下运行时捕获所有异常。该程序有多个线程,最好是它们的所有异常都被同一个处理程序捕获;我想在数据库中记录异常。有人对如何做到这一点有任何建议吗?
查看ThreadException 文档中的示例:
public static void Main(string[] args)
{
// Add the event handler for handling UI thread exceptions to the event.
Application.ThreadException += new
ThreadExceptionEventHandler(ErrorHandlerForm.Form1_UIThreadException);
// Set the unhandled exception mode to force all Windows Forms errors
// to go through our handler.
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
// Add the event handler for handling non-UI thread exceptions to the event.
AppDomain.CurrentDomain.UnhandledException += new
UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
}
您可能还希望在调试时不捕获异常,因为这样更容易调试。这有点像 hack,但为此您可以将上面的代码包装起来
if (!AppDomain.CurrentDomain.FriendlyName.EndsWith("vshost.exe")) { ... }
防止在调试时捕获异常。
编辑:检查在调试器中运行的应用程序的另一种方法,感觉比检查文件名更干净。
(见熔体、Kiquenet 和 Doug 的评论)
if(!System.Diagnostics.Debugger.IsAttached) { ... }
这避免了使用与vshost.exe
.
在 NET 4 中,默认情况下不再捕获某些异常;这些往往是指示可执行文件的(可能是致命的)损坏状态的异常,例如 AccessViolationException。
尝试在 main 方法前使用 [HandleProcessCorruptedStateExceptions] 标签,例如
using System.Runtime.ExceptionServices.HandleProcessCorruptedStateExceptions
[HandleProcessCorruptedStateExceptions]
public static int Main()
{
try
{
// Catch any exceptions leaking out of the program
CallMainProgramLoop();
}
catch (Exception e) // We could be catching anything here
{
System.Console.WriteLine(e.Message);
return 1;
}
return 0;
}
一个很好的例子可以在http://www.csharp-examples.net/ catch-unhandled-exceptions/ 找到。 基本上,把你的 main 改成:
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
Application.Run(new Form1());
}
static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
{
MessageBox.Show(e.Exception.Message, "Unhandled Thread Exception");
}
static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
MessageBox.Show((e.ExceptionObject as Exception).Message, "Unhandled UI Exception");
}
您可以为此使用N Bug库。像这样的最小设置:
NBug.Settings.Destination1 = "Type=Mail;From=me@mycompany.com;To=bugtracker@mycompany.com;SmtpServer=smtp.mycompany.com;";
AppDomain.CurrentDomain.UnhandledException += NBug.Handler.UnhandledException;
Application.ThreadException += NBug.Handler.ThreadException;
您可以开始收集有关应用程序中所有未处理错误的信息,即使它已部署到客户端。如果您不想使用 3rd 方库,则应附加到以下事件:
// These two should come before enabling visual styles or running the application
AppDomain.CurrentDomain.UnhandledException += ...
Application.ThreadException += ...
...
Application.Run(new Form1());