在定时器的回调方法中抛出异常

时间:2009-11-11 22:42:09

标签: c# exception timer backgroundworker multithreading

我无法在任何地方找到这个问题的答案......

System.Threading.Timer的回调方法(或在System.Timers.Timer的事件处理程序中)抛出的异常会发生什么。异常是否传播到创建计时器的线程还是异常丢失?

在计时器的回调函数中抛出异常有什么副作用?

向计时器的创建线程发出信号通知工作线程(回调方法)中的异常被抛出的正确方法是什么?

感谢您的时间。

4 个答案:

答案 0 :(得分:35)

异常不会传递回调用线程。如果你想要它,你可以添加一个catch块并找出一种方法来通知调用线程。如果调用线程是WinForms或WPF UI线程,则可以使用SynchronizationContext类将调用传递给UI线程。否则,您可以使用线程安全队列(或同步锁)并在另一个线程中定期检查它。

System.Timers.Timer将默默地吞下异常并继续计时器(尽管这可能会在未来的框架版本中发生变化); System.Threading.Timer将终止该计划。

答案 1 :(得分:1)

我不知道最好的选择是什么,但是当我使用回调计时器时,我通常会抛出异常并让它们冒泡到主要的回调例程,在那里我优雅地处理它们。线程继续在计时器上运行。

线程中未处理的异常(System.Threading.Timer)将停止整个程序。

答案 2 :(得分:0)

我不知道这是否是最佳解决方案,但我所做的只是一个小解决方法。我的调用线程订阅了一个事件,用于捕获来自线程的异常。因此,当某个线程发生异常时,例如在TimerElapsed事件中,然后形成catch块我将事件传递异常对象作为事件的参数。

EventHolderCallingClass:它必须定义委托和事件,如下所示。

public class EventHolderCallingClass
{    
  public delegate void HandleExceptionEventDelegate(Exception exception);
  public event HandleExceptionEventDelegate HandleExceptionEvent ;

  void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
  {
    try
    {
      //some operation which caused exception.
    }
    catch(Exception exception)
    {
      if(HandleExceptionEvent!=null)
        HandleExceptionEvent(exception) 
    }
  }
}

事件处理程序类(异常处理程序):

    public EventHandlerClassConstructor()
    {
            EventHolderCallingClass.HandleExceptionEvent += new EventHolderCallingClass.HandleExceptionEventDelegate(HandleExceptionEventHandler);            
    }

    void HandleExceptionEventHandler(Exception exception)
    {
        //handle exception here.
    }

答案 3 :(得分:0)

根据我在Windows 10 Framework 4.6下的拙劣测试,SystemTimers.Timer过去的事件使用的线程不会传播未处理的异常。 我需要向主线程触发一个事件,以通知发生未处理的异常。