计时器随机不会触发

时间:2014-05-28 13:57:55

标签: c# .net timer system.timers.timer

我的代码看起来像这样

mTestModeMetadataTimer = new System.Threading.Timer(SomeTimerCallback, null, 1000, Timeout.Infinite);

Stopwatch tmStopwatch = new Stopwatch();

private void SomeTimerCallback(object state)
{
    // doing minimal work here

    Console.WriteLine("{0}: SomeTimerCallback time: {1}", System.Threading.Thread.CurrentThread.ManagedThreadId, tmStopwatch.ElapsedMilliseconds);
    tmStopwatch.Restart();

    // Better to be on the safe side and do this slightly more than once per second, than slightly less.
    mTestModeMetadataTimer.Change(990, Timeout.Infinite);
}

一切正常,但有时候在这个控制台输出中看到的计时器事件之间会有很大的延迟。

 31: SomeTimerCallback time: 998
 21: SomeTimerCallback time: 997
 20: SomeTimerCallback time: 999
 3: SomeTimerCallback time: 989
 3: SomeTimerCallback time: 1000
 3: SomeTimerCallback time: 994
 37: SomeTimerCallback time: 999
 3: SomeTimerCallback time: 991
 29: SomeTimerCallback time: 1002
 37: SomeTimerCallback time: 1000
 3: SomeTimerCallback time: 17568
 3: SomeTimerCallback time: 999
 29: SomeTimerCallback time: 993

这是一个相当大的应用程序的一小部分。 System.Timers.Timer存在相同的行为,实际上,在整个应用程序中的其他各种时间都会发生。我将线程ID添加到此特定计时器的控制台输出中,希望能够更深入地了解为什么在正确的一秒事件中有17.5秒的随机时间。

有什么我显然做错了吗?也许我可以收集更多的数据来弄清楚为什么我的计时器表现得很有趣?

此处的任何建议都将非常感谢。

3 个答案:

答案 0 :(得分:2)

comment发生这种情况的原因是你正在耗尽线程池中的线程。因为每个线程都在使用中,所以计时器必须等待17.5秒才能使线程在运行之前可用。

我看到它的选项要么增加线程池中的max number of threads,要么使用不使用线程池的a different timer System.Timers.Timer {{3}不使用线程池(仍使用线程池启动它)或带有消息泵运行的System.Windows.Forms.Timer

答案 1 :(得分:2)

System.Threading.Timer在从CLR线程池获取的工作线程上调用事件处理程序。如果线程池处于饥饿状态,则可能会发生回调排队,直到线程被释放为止。

要检查是否耗尽了线程池,可以在调试时定期记录可用线程数:

int workerThreads;
int completitionPortThreads;
System.Threading.ThreadPool.GetAvailableThreads(out workerThreads, out completitionPortThreads);

答案 2 :(得分:0)

尝试使用Timer构造函数中的periodic:

mTestModeMetadataTimer = new System.Threading.Timer(SomeTimerCallback, null, 1000, TimeSpan.FromMilliseconds(990));

你确定你没有处于调试模式,你还有时间继续吗?