如何使用ThreadException?

时间:2011-02-01 16:00:29

标签: c# .net error-handling catch-all

我尝试使用

http://msdn.microsoft.com/en-us/library/system.windows.forms.application.threadexception.aspx#Y399

但是当我这样做时

throw new ArgumentNullException("playlist is empty");

我一无所获。我打赌我错过了一些非常明显的东西。

这是我的代码。

using System;
using System.Security.Permissions;
using System.Windows.Forms;
using System.Threading;

namespace MediaPlayer.NET
{
    internal static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlAppDomain)]
        private static void Main()
        {
            // Add the event handler for handling UI thread exceptions to the event.
            Application.ThreadException += new ThreadExceptionEventHandler(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(UnhandledException);

            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new MediaPlayerForm());
        }

        private static void UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            MessageBox.Show("UnhandledException!!!!");
        }

        private static void UIThreadException(object sender, ThreadExceptionEventArgs t)
        {
            MessageBox.Show("UIThreadException!!!!",
                            "UIThreadException!!!!", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Stop);
            Application.Exit();
        }
    }
}

2 个答案:

答案 0 :(得分:9)

您的代码运行正常,我无法想到很多可能的失败模式。当您在Windows 8之前的64位操作系统上调试32位代码时,调试器和Windows SEH之间的交互中只有一个there's a problem。这可能导致异常被吞下而没有任何诊断表单的Load事件或OnLoad()方法覆盖。检查链接的帖子以获取解决方法,最简单的一个是Project + Properties,Build选项卡,Platform Target = AnyCPU,如果你看到它,请取消选中“Prefer 32-bit”。

通常,通过不让Application.ThreadException的默认异常处理显示对话框,您正在做适当的事情。但要保持简单,就这样做:

#if (!DEBUG)
      Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException);
#endif

现在您再也不用担心ThreadException,所有异常都会触发AppDomain.UnhandledException事件处理程序。并且代码周围的#if仍允许您调试未处理的异常,调试器将在引发异常时自动停止。

将此添加到UnhandledException方法以防止Windows崩溃通知显示:

        Environment.Exit(1);

答案 1 :(得分:2)

您没有显示您正在抛出ArgumentNullException的位置。我的猜测是它在MediaPlayerForm的构造函数中(这意味着它在消息循环开始之前)或者它在不同的线程中。 Application.ThreadException仅处理在运行消息循环的Windows窗体线程上捕获的异常。