Multithreading 正确使用System.Threading.Timer

Multithreading 正确使用System.Threading.Timer,multithreading,c#-4.0,timer,Multithreading,C# 4.0,Timer,我偶然发现了一些类似以下的代码: private void SomeCallBack(object state) { lock (_lock) { try { if (_timer == null) return; _timer.Dispose(); // do some

我偶然发现了一些类似以下的代码:

private void SomeCallBack(object state)
    {
        lock (_lock)
        {
            try
            {
                if (_timer == null)
                    return;

                _timer.Dispose();
                // do some work here
            }
            catch
            {
                // handle exception
            }
            finally
            {
                _timer = new Timer(SomeCallBack, state, 100, Timeout.Infinite);
            }
        }
    }
我不明白每次执行回调时重新创建计时器的目的。我认为代码试图实现的是一次只能有一个线程执行工作。但是锁不够用吗

另外,根据msdn

请注意,调用Dispose()方法重载后可能会发生回调

这样做有什么好处吗? 如果是这样,这些好处是否证明了处理和创建计时器的开销是合理的


感谢您的帮助。

代码似乎需要一个近似周期性的计时器(不完全是周期性的,因为在计时器过期和创建新计时器之间的处理会引入抖动)。处理和重新创建计时器确实是不必要的开销。
Change
方法会更好


null的检查也很奇怪;在其他地方,必须有代码设置
\u timer
null才能生效。

代码似乎需要一个近似周期性的计时器(不完全是周期性的,因为在计时器过期和创建新计时器之间的处理会引入抖动)。处理和重新创建计时器确实是不必要的开销。
Change
方法会更好


null的检查也很奇怪;在其他地方,必须有将计时器设置为null的代码才能生效。

重新创建计时器的原因是计时器回调中的代码执行时间比计时器周期长。在这种情况下,回调的多个实例将同时运行。

重新创建计时器的原因是计时器回调中的代码执行时间比计时器周期长。在这种情况下,回调的多个实例将同时运行。

在停止计时器的函数中将计时器设置为null。如果你只是将间隔设置为100,那不是也能达到同样的效果吗?您甚至不需要使用
Change()
。函数中未修改状态,因此重新创建计时器的目的不是为实际工作传入新参数。此答案是正确的。代码正在创建一个一次性计时器。其效果是,在一次回调结束和下一次回调开始之间将有100毫秒的延迟。但由于时段设置为
Timeout.Infinite
,计时器将不会再次启动。调用
\u timer.Change(100,Timeout.Infinite)
也可以达到同样的效果,只是它不会处理计时器为
null
的情况。在现有代码中,如果计时器为null,则不进行任何处理,但会在
finally
中创建一个新的计时器。此外,这里使用锁也很奇怪。除非有多个计时器使用此回调,否则它不可能被多个线程并发调用。计时器是一次性的,因此无法进行重新进入调用。在停止计时器的函数中将计时器设置为null。如果你只是将间隔设置为100,那不是也能达到同样的效果吗?您甚至不需要使用
Change()
。函数中未修改状态,因此重新创建计时器的目的不是为实际工作传入新参数。此答案是正确的。代码正在创建一个一次性计时器。其效果是,在一次回调结束和下一次回调开始之间将有100毫秒的延迟。但由于时段设置为
Timeout.Infinite
,计时器将不会再次启动。调用
\u timer.Change(100,Timeout.Infinite)
也可以达到同样的效果,只是它不会处理计时器为
null
的情况。在现有代码中,如果计时器为null,则不进行任何处理,但会在
finally
中创建一个新的计时器。此外,这里使用锁也很奇怪。除非有多个计时器使用此回调,否则它不可能被多个线程并发调用。计时器是一次性的,因此无法进行重新进入呼叫。