与System.Threading.Timer在C#中工作 [英] Working with System.Threading.Timer in C#

查看:529
本文介绍了与System.Threading.Timer在C#中工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个计时器对象。我希望它是每分钟运行一次。具体来说,它应该运行 OnCallBack 法而 OnCallBack 方法运行变得无效。一旦 OnCallBack 方法完成,它( OnCallBack )重新启动一个定时器。

I've a timer object. I want it to be run every minute. Specifically, it should run a OnCallBack method and gets inactive while a OnCallBack method is running. Once a OnCallBack method finishes, it (a OnCallBack) restarts a timer.

下面是我现在所拥有的:

Here is what I have right now:

private static Timer timer;

private static void Main()
{
    timer = new Timer(_ => OnCallBack(), null, 0, 1000 * 10); //every 10 seconds
    Console.ReadLine();
}

private static void OnCallBack()
{
    timer.Change(Timeout.Infinite, Timeout.Infinite); //stops the timer
    Thread.Sleep(3000); //doing some long operation
    timer.Change(0, 1000 * 10);  //restarts the timer
}

不过,这似乎是不工作。它运行速度非常快,每3秒。即使如果提高一个周期(1000 * 10)。现在看来似乎视若无睹,以 1000 * 10

我做了什么错?

推荐答案

这是System.Threading.Timer的不正确使用。当你实例化的定时器,你应该总是做到以下几点:

This is not the correct usage of the System.Threading.Timer. When you instantiate the Timer, you should almost always do the following:

_timer = new Timer( Callback, null, TIME_INTERVAL_IN_MILLISECONDS, Timeout.Infinite );

这将指示计时器滴答只有一次,当时间间隔已过。然后在你的回调函数,一旦工作完成,而不是之前更改计时器。例如:

This will instruct the timer to tick only once when the interval has elapsed. Then in your Callback function you Change the timer once the work has completed, not before. Example:

private void Callback( Object state )
{
    // Long running operation
   _timer.Change( TIME_INTERVAL_IN_MILLISECONDS, Timeout.Infinite );
}

因此​​,没有必要对锁定机构,因为没有并发。定时器将触发下一回调之后的下一个时间间隔已经经过+长期运行运转时

Thus there is no need for locking mechanisms because there is no concurrency. The timer will fire the next callback after the next interval has elapsed + the time of the long running operation.

如果您需要在确切的N毫秒运行定时器,那么我建议你用秒表测量长时间运行操作的时间,然后调用相应的更改方法:

If you need to run your timer at exactly N milliseconds, then I suggest you measure the time of the long running operation using Stopwatch and then call the Change method appropriately:

private void Callback( Object state )
{
   Stopwatch watch = new Stopwatch();

   watch.Start();
   // Long running operation

   _timer.Change( Math.Max( 0, TIME_INTERVAL_IN_MILLISECONDS - watch.ElapsedMilliseconds ), Timeout.Infinite );
}

编辑:

我强烈鼓励任何人这样做。NET和使用谁没有看过杰弗里里希特的书CLR - 通过C# CLR,阅读,尽快为。计时器和线程池在伟大的细节也进行了解释。

I strongly encourage anyone doing .NET and is using the CLR who hasn't read Jeffrey Richter's book - CLR via C#, to read is as soon as possible. Timers and thread pools are explained in great details there.

这篇关于与System.Threading.Timer在C#中工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆