如何获得Timer Elapsed事件中发生的异常?

Cla*_*ack 35 c# multithreading timer

我正在使用Windows窗体应用程序并且使用System.Timers.Timer来定期检查数据库中的数据.

如何将计时器Elapsed事件处理程序中发生的异常传递到主应用程序中?如果我使用下面的代码,异常会被"吞噬",主应用程序永远不会得到它(即使我有ThreadException和UnHandledException的处理程序).

// Main Form
Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

// Manager class
private System.Timers.Timer _timer;

    void _timer_Elapsed(object sender, ElapsedEventArgs e)
    {
        try
        {
            doSomeDatabaseActions();
        }
        catch (Exception ex)
        {
            throw new ApplicationException("How do I get this error back into main thread...", ex);
        }
    }
Run Code Online (Sandbox Code Playgroud)

svi*_*ick 31

如果您无权访问主线程,则可以在另一个非计时器线程上抛出异常:

catch (Exception exception)
{
    ThreadPool.QueueUserWorkItem(
        _ => { throw new Exception("Exception on timer.", exception); });
}
Run Code Online (Sandbox Code Playgroud)


Ken*_*art 25

由于System.Timers.Timer燕子在事件处理程序抛出的任何异常,你需要将异常编组到另一个线程(可能是UI线程).您可以通过Control.Invoke或通过将错误信息存储在成员变量中并让UI线程在操作完成后检查此错误信息来执行此操作.如果null不是,则UI可以抛出.

来自MSDN:

在.NET Framework 2.0及更早版本中,定时器组件捕获并抑制由事件处理程序经过的事件引发的所有异常.在将来的.NET Framework版本中,此行为可能会发生更改.

刚刚在.NET 4.0中检查过,此行为尚未更改.

  • 是否有任何新方法可以捕获.net 4.5中的意外错误?它仍然吞下并且无论如何都没有记录错误而没有在try catch中包装整个_timer_Elapsed? (2认同)