C# 在不关闭应用程序的情况下处理全局异常?

C# 在不关闭应用程序的情况下处理全局异常?,c#,.net,winforms,exception-handling,global,C#,.net,Winforms,Exception Handling,Global,我抛出了各种自定义异常,但没有考虑我的代码 其中一些是可从恢复的,因此我希望全局处理程序捕获它们,显示警告,然后继续 我找到了AppDomain.UnhandledException事件,该事件具有IsTerminating参数,但它是只读的 是否有某种事件或其他方式可以全局捕获异常,从而仍能让您处理异常并继续 (这是表单,但我也对WPF解决方案感兴趣)您可以使用global.asax和 void Application_Error(object sender, EventArgs e) { }

我抛出了各种自定义异常,但没有考虑我的代码

其中一些是可从恢复的,因此我希望全局处理程序捕获它们,显示警告,然后继续

我找到了
AppDomain.UnhandledException
事件,该事件具有
IsTerminating
参数,但它是只读的

是否有某种事件或其他方式可以全局捕获异常,从而仍能让您处理异常并继续


(这是表单,但我也对WPF解决方案感兴趣)

您可以使用global.asax和

void Application_Error(object sender, EventArgs e)
{
}
事件捕获页面上未捕获的错误

在这种情况下,您可以使用多种方法,但其中一种方法如下:

void Application_Error(object sender, EventArgs e)
{
    Exception opException = Server.GetLastError();

    switch (opException.GetBaseException().GetType().Name)
    {
        case "OptimisticConcurrencyException":
                        //display a friendly message
                    break;
    }


    Server.ClearError();

}

或者类似的

您可以使用global.asax和

void Application_Error(object sender, EventArgs e)
{
}
事件捕获页面上未捕获的错误

在这种情况下,您可以使用多种方法,但其中一种方法如下:

void Application_Error(object sender, EventArgs e)
{
    Exception opException = Server.GetLastError();

    switch (opException.GetBaseException().GetType().Name)
    {
        case "OptimisticConcurrencyException":
                        //display a friendly message
                    break;
    }


    Server.ClearError();

}
或者类似的东西

试试类似的东西:

AppDomain.CurrentDomain.UnhandledException += AppDomainUnhandledException;

public static void AppDomainUnhandledException(object sender, UnhandledExceptionEventArgs e)
{
    // You might have to try changing this to your custom exception type and then have overloads or pass it as an object and cast it in the HandleException method
    HandleException(e.ExceptionObject as Exception);
}

private static void HandleException(Exception exception)
{
    if (exception == null) return;

    // Do a check in here against the exceptions that you want to handle or don't want to handle and either display a message, log, quit, etc
}
我没有注意到winforms,我已经很长时间没有做表单了,所以这是WPF,可能会起作用,或者可能需要进行调整。

尝试以下方法:

AppDomain.CurrentDomain.UnhandledException += AppDomainUnhandledException;

public static void AppDomainUnhandledException(object sender, UnhandledExceptionEventArgs e)
{
    // You might have to try changing this to your custom exception type and then have overloads or pass it as an object and cast it in the HandleException method
    HandleException(e.ExceptionObject as Exception);
}

private static void HandleException(Exception exception)
{
    if (exception == null) return;

    // Do a check in here against the exceptions that you want to handle or don't want to handle and either display a message, log, quit, etc
}

没有注意到winforms,我已经很长时间没有做表单了,所以这是WPF,可能会工作,或者可能需要调整。

已经找到了解决方案。使用
Application.ThreadException
而不是
AppDomain.unhandledeexception
。但您还必须告诉它在UI线程上也给出异常:

public static void SetupGlobalExceptionHandler()
{
    Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
    Application.ThreadException += OnException;
}

static void OnException(object sender, ThreadExceptionEventArgs args)
{
    MessageBox.Show("There was a problem. Error is:\n\n" + args.Exception.Message);
}

我们已经找到了解决办法。使用
Application.ThreadException
而不是
AppDomain.unhandledeexception
。但您还必须告诉它在UI线程上也给出异常:

public static void SetupGlobalExceptionHandler()
{
    Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
    Application.ThreadException += OnException;
}

static void OnException(object sender, ThreadExceptionEventArgs args)
{
    MessageBox.Show("There was a problem. Error is:\n\n" + args.Exception.Message);
}

这是一个旧线程,但Dispatcher.UnhandledException事件在其事件参数上有一个已处理的参数,可用于阻止应用程序关闭

protected override void OnStartup(StartupEventArgs e)
{
    Dispatcher.UnhandledException += Dispatcher_UnhandledException;
}
private void Dispatcher_UnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
    HandleException(e.Exception);//your handler
    e.Handled = true;
}

这是一个旧线程,但Dispatcher.UnhandledException事件在其事件参数上有一个已处理的参数,可用于阻止应用程序关闭

protected override void OnStartup(StartupEventArgs e)
{
    Dispatcher.UnhandledException += Dispatcher_UnhandledException;
}
private void Dispatcher_UnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
    HandleException(e.Exception);//your handler
    e.Handled = true;
}

正如我说的,这是表单,不是ASP。啊,对不起,我错了,我听到了“表单”,只是假设了“网络表单”!!FacePalm正如我说的,这是表单,不是ASP。啊,对不起,我弄错了,我听到了“表单”,只是假设了“网络表单”!!可能重复:可能重复:这正是我正在做的。当事件触发时,运行时已经决定终止应用程序。我所能做的就是显示一条消息。@GazTheDestroyer如果用try/catch包装主应用程序运行命令,并将其传递给HandleException,那么如果我包装应用程序,您应该能够调用shutdown/exit yourself。Run然后在引发异常时它将退出。我不想退出应用程序。@GazTheDestroyer只有在您给它一个显式的Environment.exit()或Application.Current.Shutdown()命令时,它才会退出,因为您正在捕获错误,您可以根据需要处理它。老实说,如果您遇到未经处理的错误,您应该让应用程序退出,因为您可能会出现错误数据或奇怪的bug。您应该只捕获所有错误,以便找出在何处提供正确的错误处理代码。如果我在try catch中包装Application.Run(),则该捕获在Run()函数之外,即我的应用程序在捕获时不再运行,因此很遗憾不可行。非常感谢你的帮助,但我想我现在已经解决了。这正是我正在做的。当事件触发时,运行时已经决定终止应用程序。我所能做的就是显示一条消息。@GazTheDestroyer如果用try/catch包装主应用程序运行命令,并将其传递给HandleException,那么如果我包装应用程序,您应该能够调用shutdown/exit yourself。Run然后在引发异常时它将退出。我不想退出应用程序。@GazTheDestroyer只有在您给它一个显式的Environment.exit()或Application.Current.Shutdown()命令时,它才会退出,因为您正在捕获错误,您可以根据需要处理它。老实说,如果您遇到未经处理的错误,您应该让应用程序退出,因为您可能会出现错误数据或奇怪的bug。您应该只捕获所有错误,以便找出在何处提供正确的错误处理代码。如果我在try catch中包装Application.Run(),则该捕获在Run()函数之外,即我的应用程序在捕获时不再运行,因此很遗憾不可行。非常感谢你的帮助,但我想我现在已经解决了。