C# 中的 System.Threading.Timer 似乎不起作用.它每 3 秒运行得非常快 [英] System.Threading.Timer in C# it seems to be not working. It runs very fast every 3 second

查看:14
本文介绍了C# 中的 System.Threading.Timer 似乎不起作用.它每 3 秒运行得非常快的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个计时器对象.我希望它每分钟运行一次.具体来说,它应该运行 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.

这是我现在所拥有的:

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

However, it seems to be not working. It runs very fast every 3 second. Even when if raise a period (1000*10). It seems like it turns a blind eye to 1000 * 10

我做错了什么?

推荐答案

这不是 System.Threading.Timer 的正确用法.当您实例化 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 毫秒运行计时器,那么我建议您使用 Stopwatch 测量长时间运行操作的时间,然后适当地调用 Change 方法:

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 的人,如果他们还没有阅读 Jeffrey Richter 的书 - CLR via C#,请尽快阅读.那里对定时器和线程池进行了非常详细的解释.


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.

这篇关于C# 中的 System.Threading.Timer 似乎不起作用.它每 3 秒运行得非常快的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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