WinForms全局异常处理?

ykh*_*ykh 23 c# winforms

我已经实现了一个软件,它有一个DLL库,其中包含一大堆类,其中包括我的软件的所有方法.

现在我希望能够处理一些全局错误,例如错误#26,这对所有这些类都没有网络相关错误,而不是去每个类并添加它.怎么做 ?

gid*_*eon 21

由于它是一个winforms应用程序,您可以将其包含Application.Run(new MainForm());在try catch块中.

static void Main()
{
try {
 Application.Run(new MainForm());
} catch(SystemException)//just as an example 
{
 //log or handle the error here. 
}
}
Run Code Online (Sandbox Code Playgroud)

我不知道这种解决方案会带来什么影响,但我只是告诉你你需要什么.

其他选项是订阅Application.ThreadException事件.

在这里阅读更多:unhandledexceptions

还有AppDomain.UnhandledException,您应该在MSDN上阅读它们之间的区别.

来自MSDN:

对于某些应用程序模型,如果主应用程序线程中发生未处理的异常,则UnhandledException事件可被其他事件抢占.

在使用Windows窗体的应用程序中,主应用程序线程中的未处理异常会导致引发Application.ThreadException事件.如果处理此事件,则默认行为是未处理的异常不会终止应用程序,尽管应用程序处于未知状态.在这种情况下,不会引发UnhandledException事件.可以通过使用应用程序配置文件或使用Application.SetUnhandledExceptionMode方法在连接ThreadException事件处理程序之前将模式更改为UnhandledExceptionMode.ThrowException来更改此行为.这仅适用于主应用程序线程.针对在其他线程中引发的未处理异常引发UnhandledException事件.


Fis*_*aen 16

如果#26是例外,那么您可以使用AppDomain.CurrentDomain.UnhandledException事件.如果它只是一个返回值,那么我认为没有任何机会全局处理它.


Rah*_*odi 8

在C#Windows应用程序中引用了集中式异常处理,我找到了一个很好的解决方案:

static class Program
{
    [STAThread]
    static void Main()
    {
        // Add handler to handle the exception raised by main threads
        Application.ThreadException += 
        new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);

        // Add handler to handle the exception raised by additional threads
        AppDomain.CurrentDomain.UnhandledException += 
        new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());

        // Stop the application and all the threads in suspended state.
        Environment.Exit(-1);            
    }

    static void Application_ThreadException
        (object sender, System.Threading.ThreadExceptionEventArgs e)
    {// All exceptions thrown by the main thread are handled over this method

        ShowExceptionDetails(e.Exception);
    }

    static void CurrentDomain_UnhandledException
        (object sender, UnhandledExceptionEventArgs e)
    {// All exceptions thrown by additional threads are handled in this method

        ShowExceptionDetails(e.ExceptionObject as Exception);

        // Suspend the current thread for now to stop the exception from throwing.
        Thread.CurrentThread.Suspend();
    }

    static void ShowExceptionDetails(Exception Ex)
    {
        // Do logging of exception details
        MessageBox.Show(Ex.Message, Ex.TargetSite.ToString(), 
                MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
}  
Run Code Online (Sandbox Code Playgroud)

在上面的类中,我们将为两个事件附加一个事件处理程序.主方法启动后,最好附加这些事件.

Application.ThreadException - 在主线程中抛出异常时将引发此事件.如果我们添加一个事件处理程序,则通过该方法处理异常.

AppDomain.CurrentDomain.UnhandledException - 当在应用程序中使用的其他线程中引发异常时,将引发此事件.这里更糟糕的情况是,一旦处理程序的执行结束,异常再次抛出而应用程序结束.这需要处理.在这里,我使用了一些代码来处理这种情况,并继续执行应用程序而不会中断.

我用来克服这种情况的逻辑只是暂停事件处理程序中的线程,以便应用程序继续正常工作.在暂停此线程时再次出现问题.当主窗体关闭时,应用程序通常需要退出,但是当线程处于挂起状态时,应用程序仍将继续运行.因此,要完全退出应用程序并停止进程,必须在main方法结束之前调用Environment.Exit(-1).


小智 6

首先,您应该添加:

Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
Run Code Online (Sandbox Code Playgroud)

之后,您可以捕获异常,例如:

[STAThread]
    static void Main()
    {

        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
        Application.ThreadException += ApplicationThreadException;
        AppDomain.CurrentDomain.UnhandledException += CurrentDomainOnUnhandledException;

        if (DataBaseMNG.Init())
        {
            Application.Run(new MainForm());
        }
    }

    /// <summary>
    /// Global exceptions in Non User Interfarce(other thread) antipicated error
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private static void CurrentDomainOnUnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        var message =
            String.Format(
                "Sorry, something went wrong.\r\n" + "{0}\r\n" + "{1}\r\n" + "please contact support.",
                ((Exception)e.ExceptionObject).Message, ((Exception)e.ExceptionObject).StackTrace);
        MessageBox.Show(message, @"Unexpected error");
    }

    /// <summary>
    /// Global exceptions in User Interfarce antipicated error
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private static void ApplicationThreadException(object sender, ThreadExceptionEventArgs e)
    {
        var message =
            String.Format(
                "Sorry, something went wrong.\r\n" + "{0}\r\n" + "{1}\r\n" + "please contact support.",
                e.Exception.Message, e.Exception.StackTrace);
        MessageBox.Show(message, @"Unexpected error");
    }
Run Code Online (Sandbox Code Playgroud)