.Net app线程/计时器性能

时间:2012-06-26 15:35:54

标签: c# multithreading

我正在开发一个启动System.Threading.Timer的应用程序,它可以快速读取/写入串口(每100毫秒)。计时器的回调方法如下所示: -

if (_timerTaskRunning)
{
    Debug.WriteLine("still running");
    return;
}

_timerTaskRunning = true;

... do the serial write/read here ...

_timerTaskRunning = false;

_timerTaskRunning标志是一个安全措施,可确保代表在前一个计时器"周期"还没有完成,也就是说它花了超过100毫秒。

当我第一次启动应用程序时,我看到来自if语句的十几个调试消息。然后它会安定下来,但我会在7或8秒后看到另一组消息。它再次安定下来,每隔一段时间我就会看到一组消息出现在不同的数字中。

我假设第一组消息是由于应用程序仍然启动,对象/ UI初始化等等而导致计时器委托缓慢运行引起的,而后续消息可能是由垃圾收集引起的每隔一段时间经常放慢脚步?它不是串口,因为我看到了与#34; mock"相同的行为。串口。

我已经尝试将计时器的第一次运行延迟了几秒钟,但没有区别 - 在计时器启动后的第一秒左右,我仍然收到一批调试消息。它不是世界末日跳过一些计时器任务,但知道可能导致它们的原因会很有趣。我可以做些什么来进一步调查原因,例如会不会对事情有所了解?我之前没有使用它,你会建议使用哪个计数器?

2 个答案:

答案 0 :(得分:3)

听起来你有一个重入问题。基本上你的_timerTaskRunning可能不会因为竞争条件而起到保障作用。

  1. 使用System.Timers.Timer代替System.Threading.Timer
  2. 将Timer.AutoReset设置为false。这将解决您的引人入胜的问题,因为在您明确要求之前,它不会给您回电。
  3. 当您需要再次使用时,请在计时器上调用Start()(您可能需要调整间隔以说明执行时间)
  4. 如果您有多个可以调用start的线程,则需要同步对它的调用。

答案 1 :(得分:2)

您的_timerTaskRunning会被多个线程更新。您需要使用锁定来使其成为线程安全的。

但是,我根本不会使用计时器。我已经实现了一个非renetrant计时器here。它使用AutoResetEvent WaitOne并超时,以确保不重新进入。