C# 处理未处理的异常问题
我想为代码中可能没有捕获到的所有意外异常设置一些处理程序。在C# 处理未处理的异常问题,c#,exception,C#,Exception,我想为代码中可能没有捕获到的所有意外异常设置一些处理程序。在Program.Main()中,我使用了以下代码: AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(ErrorHandler.HandleException); 但它没有像我预期的那样起作用。当我在调试模式下启动应用程序并抛出异常时,它确实调用了处理程序,但随后Visual Studio中的异常帮助程序弹出,就好像
Program.Main()
中,我使用了以下代码:
AppDomain.CurrentDomain.UnhandledException
+= new UnhandledExceptionEventHandler(ErrorHandler.HandleException);
但它没有像我预期的那样起作用。当我在调试模式下启动应用程序并抛出异常时,它确实调用了处理程序,但随后Visual Studio中的异常帮助程序弹出,就好像异常发生时没有任何处理一样。我在处理程序中尝试了Application.Exit(),但效果不佳
我希望实现的是,使用我的处理程序处理异常,然后应用程序很好地关闭。是否有其他方法来执行此操作,或者我是否以错误的方式使用了上面的代码?这是因为您正在以调试模式通过Visual Studio运行它。如果您在其他地方发布并安装应用程序,将只处理您的全局异常处理程序。这是因为您在调试模式下通过Visual Studio运行它。如果你在其他地方发布并安装你的应用程序,除了你的全局异常处理程序外,什么都不会被处理。注意,未处理的异常仍然是非常致命的;您只能真正地将其用于日志记录,或者可能是匆忙关闭。此应用程序和
应用程序.ThreadException
都不能用作错误的全局接收器
更好的方法是添加适当的处理—例如,围绕整个
Main()
逻辑。请注意,即使这样也无法捕获一些异常,例如表单加载过程中的错误(这会变得特别糟糕-您可以通过附加的调试器捕获它们,但不能没有调试器)。请注意,未处理的异常仍然是非常致命的;您只能真正地将其用于日志记录,或者可能是匆忙关闭。此应用程序和应用程序.ThreadException
都不能用作错误的全局接收器
更好的方法是添加适当的处理—例如,围绕整个
Main()
逻辑。请注意,即使这样也无法捕获一些异常,例如表单加载期间的错误(这会变得特别糟糕-您可以使用附加的调试器来捕获它们,但不能不使用调试器)。通常我使用类似的方法来尝试捕获所有意外的顶级异常
using System;
static class Program
{
[STAThread]
static void Main(string[] argv)
{
try
{
AppDomain.CurrentDomain.UnhandledException += (sender,e)
=> FatalExceptionObject(e.ExceptionObject);
Application.ThreadException += (sender,e)
=> FatalExceptionHandler.Handle(e.Exception);
// whatever you need/want here
Application.Run(new MainWindow());
}
catch (Exception huh)
{
FatalExceptionHandler.Handle(huh);
}
}
static void FatalExceptionObject(object exceptionObject) {
var huh = exceptionObject as Exception;
if (huh == null) {
huh = new NotSupportedException(
"Unhandled exception doesn't derive from System.Exception: "
+ exceptionObject.ToString()
);
}
FatalExceptionHandler.Handle(huh);
}
}
也许这对你也有帮助?此主代码通过一个方法调用来路由捕获意外顶级异常的所有三种方法。您现在只需要一个静态类FatalExceptionHandler
,它在其Handle
方法中包含顶级异常处理
实际上,任何应用程序开发人员都知道,实际上只有两件事要做:
FatalExceptionHandler
报告,以使其自己为人所知,并阻止可能受损的程序在损坏状态下工作
死掉的程序不会说谎…;-) 通常我会使用类似的方法来尝试捕获所有意外的顶级异常
using System;
static class Program
{
[STAThread]
static void Main(string[] argv)
{
try
{
AppDomain.CurrentDomain.UnhandledException += (sender,e)
=> FatalExceptionObject(e.ExceptionObject);
Application.ThreadException += (sender,e)
=> FatalExceptionHandler.Handle(e.Exception);
// whatever you need/want here
Application.Run(new MainWindow());
}
catch (Exception huh)
{
FatalExceptionHandler.Handle(huh);
}
}
static void FatalExceptionObject(object exceptionObject) {
var huh = exceptionObject as Exception;
if (huh == null) {
huh = new NotSupportedException(
"Unhandled exception doesn't derive from System.Exception: "
+ exceptionObject.ToString()
);
}
FatalExceptionHandler.Handle(huh);
}
}
也许这对你也有帮助?此主代码通过一个方法调用来路由捕获意外顶级异常的所有三种方法。您现在只需要一个静态类FatalExceptionHandler
,它在其Handle
方法中包含顶级异常处理
实际上,任何应用程序开发人员都知道,实际上只有两件事要做:
FatalExceptionHandler
报告,以使其自己为人所知,并阻止可能受损的程序在损坏状态下工作
死掉的程序不会说谎…;-) 也许你要找的是
Environment.Exit(interrorcode)
也许你要找的是Environment.Exit(interrorcode)
这种行为是设计出来的
但是有一个解决办法
要么调用Process.GetCurrentProcess().Kill()代码>在处理程序中,或者干脆不让处理程序结束
请查看以下示例:
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();
}
}
当然,这不应该是异常的默认接收器
但这样做是为了优雅地报告异常。这种行为是出于设计
但是有一个解决办法
要么调用Process.GetCurrentProcess().Kill()代码>在处理程序中,或者干脆不让处理程序结束
请查看以下示例:
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();
}
}
当然,这不应该是异常的默认接收器
但这样做是为了优雅地报告异常。那么为什么不在Main()中捕获它们呢?“我知道”是对“错误接收器”部分的回答。有人教我,总的来说,试抓是一件不应该做的事。但是,我必须诚实地说,我不知道为什么这是一种糟糕的方法(当然,如果我捕获了代码中可以想到的所有异常),那么为什么不在Main()中捕获它们呢?“我知道”是对“错误接收器”部分的回答。我是被教会的