AppDomain.UnhandledException的UnhandledExceptionMode.ThrowException

时间:2014-10-17 11:06:00

标签: c# exception appdomain unhandled

我想为当前AppDomain设置UnhandledExceptionMode.ThrowException,而不仅仅是Application-Thread。另一个线程的异常也应该由我的CurrentDomain_UnhandledException事件处理程序处理。这可能吗?这是我的代码:

static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException);
        AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }

    static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        File.AppendAllText("Log.txt", ((Exception)e.ExceptionObject).Message + Environment.NewLine);
    }
}

1 个答案:

答案 0 :(得分:2)

也许您正在寻找Application.ThreadException提供的行为? http://msdn.microsoft.com/en-us/library/system.windows.forms.application.threadexception%28v=vs.80%29.aspx

根据您的评论,实现所需行为的一种方法是从.Net 1启用旧的未处理的异常策略。

在App.config中:

    

<runtime>
    <legacyUnhandledExceptionPolicy enabled="1" />
</runtime>

然后像这样修改你的主要方法:

class Program
{
    [STAThread]
    static void Main(string[] args)
    {
        try
        {
            AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;

            ThreadPool.QueueUserWorkItem((object state) =>
            {
                throw new Exception("Exception thrown on Background Thread");
            });

            throw new Exception("Exception at the end of Main");
        }
        catch (Exception exception)
        {
            // Exceptions thrown on the Main Thread will pass through here
            HandleUnhandledException(exception);
        }
    }

    static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        // Exceptions thrown on Background Threads will pass through here
        HandleUnhandledException((Exception)e.ExceptionObject);
    }

    static void HandleUnhandledException(Exception exception)
    {
        // TODO: Write your Unhandled Exception routine here
        Console.WriteLine(exception.Message);
    }
}

启用旧版异常策略会导致主线程忽略后台线程上的异常。它们只会被无法处理的异常事件监听器看到。需要处理主线程上的异常以防止.NET Unhandled Exception对话框,但是,通过使用共享方法,您可以重用异常处理代码。


您附加到AppDomain.UnhandledException 的事件处理程序将捕获源自AppDomain中所有线程的所有未处理异常。如果您从图片中删除Windows窗体,这里有一些代码说明它:

class Program
{
    [STAThread]
    static void Main(string[] args)
    {
        AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;

        ThreadPool.QueueUserWorkItem((object state) =>
        {
            throw new Exception("Exception thrown on Background Thread");
        });

        throw new Exception("Exception at the end of Main");
    }

    static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        Console.WriteLine(((Exception)e.ExceptionObject).Message);
    }
}

如果运行此命令,您将看到在应用程序崩溃之前,由于Main末尾的未处理异常,两个异常消息都会立即写入控制台。 (注意这确实说明事件处理程序适用于两个异常,但它具有竞争条件 - 在现实生活中,未处理的异常将在下一个异常之前终止AppDomain可以提出