【问题标题】:Dispose WaitOne function stuck timer callbackDispose WaitOne 函数卡住定时器回调
【发布时间】:2014-10-20 06:38:22
【问题描述】:

我有一个计时器,它的回调做一些事情:

计时器:

dataProcessingTimer = new System.Threading.Timer(new TimerCallback(DataProcessingTimerHandler), null, 0, _dataProcessingTimerPollingInterval);

回调:

void DataProcessingTimerHandler(object param)
{
    // some code.. (sometimes the stop function called from here).
}

当我想停止计时器时,我调用了我的停止函数:

public void Stop()
{

    if (_dataProcessingTimer != null)
    {
         ManualResetEvent timerDisposeHandler = new ManualResetEvent(false);
         _dataProcessingTimer.Dispose(timerDisposeHandler);
         _dataProcessingTimer = null;

         timerDisposeHandler.WaitOne();
    }

}

timerDisposeHandler.WaitOne(); 使用确保 dispose 在 stop 函数后面的代码之前完成。

但有时当在回调的中间调用停止函数时,waitone 卡住了。

似乎 WaitOne 卡住了回调,但我不明白为什么会这样,是不是在它自己的线程中找不到计时器回调?为什么stop函数的线程会卡住呢?

如果有人可以向我解释情况并给我解决方案,我会很高兴。

【问题讨论】:

标签: c# multithreading timer callback manualresetevent


【解决方案1】:

你正在死锁你的定时器回调。来自MSDN:“在所有当前排队的回调完成之前,不会释放计时器。”

换句话说,System.Threading.Timer 类在您的回调完成之前不会自行释放。但是您的回调拒绝完成,直到 Stop() 方法返回。并且 Stop() 方法在 dispose 完成之前拒绝返回。

如果您确实必须等待处理完成的通知,您有两个选择:延迟对 Stop() 的调用,直到回调完成后;或延迟等待,直到回调完成后。您不能做的是尝试在阻止您正在等待的事件的同一方法中等待。

恕我直言,最好的解决方案是不要等待 Dispose() 完成。这样做有什么意义?你真的需要等待吗?如果有,为什么?

【讨论】:

  • 我真的需要等待,因为停止之后的代码需要使用我在回调中收到的数据,所以我必须等待它结束。
  • 如果您的代码需要您在回调中收到的数据,那么您肯定不想从回调中调用 Stop(),因为那只是另一层等待发生的僵局。我认为让回调发出停止信号是有问题的,但假设你真的需要它,那么你需要进行设置,以便回调简单地发出一些代码,这些代码将在稍后/其他地方执行以实际执行停止然后处理回调为您收集的所有数据。
猜你喜欢
  • 2011-01-24
  • 2021-07-27
  • 2021-04-13
  • 2016-10-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多