尝试隔离问题时尽可能简化了此问题。我假设它与单独线程中引发的异常有关由Timer.Elapsed引发的异常未被尝试的全局异常事件处理程序捕获Visual C#
让我们来看看WindowsFormApp。
设程序类源看起来像这样
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(UnhandledExceptionOccurred);
Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(UnhandledExceptionOccurred);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
public static void UnhandledExceptionOccurred(object sender, UnhandledExceptionEventArgs e)
{
var x = (Exception)e.ExceptionObject;
MessageBox.Show("Unhandled Exception\r\n" + x.Message);
}
public static void UnhandledExceptionOccurred(object sender, ThreadExceptionEventArgs e_thread)
{
var x = e_thread.Exception;
MessageBox.Show("Thread Exception\r\n" + x.Message);
}
}
很抱歉,如果这已经是势不可挡。让我试图简化发生在这个岗位上的知识积累。
静态方法UnhandledExceptionOccurred()
有一个覆盖。这些方法用作未处理线程异常的事件处理程序,以及来自主线程的未处理异常。 (如果这不正确,我想纠正这一点,但这是我的理解)。
假设在主形式中,当一个按钮被点击则抛出异常
private void button1_Click(object sender, EventArgs e)
{
throw new Exception("Exception 1");
}
假设按钮被点击。该例外被捕获就好了此消息框阅读
“线程异常异常1”
现在(几乎完成)想在Form1的构造函数中,我创建了一个System.Timers.Timer
,具有时间间隔为5000毫秒,其事件处理程序引发了异常。
System.Timers.Timer T;
public Form1()
{
InitializeComponent();
T = new System.Timers.Timer();
T.Interval = 5000; //Miliseconds;
T.Elapsed += new ElapsedEventHandler(TimerElapsed);
T.Start();
}
和事件处理程序:
public void TimerElapsed(object sender, ElapsedEventArgs e)
{
T.Stop();
throw new Exception("Exception From Timer Elapsed");
}
现在假设的形式开始,并在5秒通过。
没有消息框出现,并且没有WindowsFormError框弹出。该程序默默吞下异常,我可以点击之前提到的按钮,并使消息框像以前一样出现。
这是怎么回事?
我知道这可能与计时器正在进行的线程有关。我已经搜索和搜索,并且还没有找到一种方法来访问计时器正在使用的线程的内部,这样我就可以为它的UnhandledException和ThreadException事件添加一些事件处理程序。我可以使用System.Threading.Timers Timer
。
我注意到这种类型的定时器的构造函数需要CallbackMethod
? (什么是回调方法?)也许这个回调方法可以用来将未处理的异常路由回MainUI线程?
任何/所有输入赞赏。
这是'System.Timers.Timer'的一个已知问题 - 定时器回调中的任何未处理的异常都被框架吞噬。 *始终*在'System.Timers.Timer'回调提供自己的异常处理程序。或者,确实不要使用'System.Timers.Timer'。如果你打算为'System.Threading.Timer',知道的[分歧](https://stackoverflow.com/q/1416803/)。 –
有没有你不使用'System.Windows.Forms.Timer'一个原因? – lesscode
你也可以设置'SynchronizingObject'您当前的定时器(也许)你'Form'对象。那么这将调用UI线程上的回调和异常不会被吞噬。 – lesscode