如何让计时器滴答跳过如果previous线程仍然忙 [英] How to let Timer skip tick if the previous thread is still busy

查看:157
本文介绍了如何让计时器滴答跳过如果previous线程仍然忙的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个窗口服务,这应该是在db为每60秒新行检查某个表。对于添加,每一个新的行,我需要做的,可能有时会超过60秒服务器上的一些沉重的处理。

I created a windows service, that is supposed to check a certain table in the db for new rows every 60 seconds. For every new row that was added, I need to do some heavy processing on the server that could sometimes take more than 60 seconds.

我在服务,蜱每60秒,并调用想要的方法创建一个Timer对象。结果
因为我不希望这个计时器来处理,而新发现的蜱行,我裹在锁定{} 块的方法,所以这不会是另一个访问主题。

I created a Timer object in my service, that ticks every 60 seconds and invokes the wanted method.
Since I don't want this timer to tick while processing the new lines found, I wrapped the method in a lock { } block, so this won't be accessible by another thread.

这看起来是这样的:

Timer serviceTimer = new Timer();
serviceTimer.Interval = 60;
serviceTimer.Elapsed += new ElapsedEventHandler(serviceTimer_Elapsed);
serviceTimer.Start();

void serviceTimer_Elapsed(object sender, ElapsedEventArgs e)
{
    lock (this)
    {
        // do some heavy processing...
    }
}

现在,我想知道 - 结果
如果我的计时器刻度,并发现了大量的新行的分贝,而现在的处理将超过60秒,下刻度线不会做任何处理,直到完成了previous之一。这就是我想要的效果。

Now, I'm wondering -
If my timer ticks, and finds a lot of new rows on the db, and now the processing will take more than 60 seconds, the next tick won't do any processing till the previous one finished. This is the effect I want.

但现在,将serviceTimer_Elapsed方法立刻熄灭,一旦第一处理结束,还是会等待计时器再次打勾。

But now, will the serviceTimer_Elapsed method go off immediatly once the first processing was finished, or will it wait for the timer to tick again.

我希望发生的是 - 如果处理需要超过60秒,比定时器会注意到线程被锁定,等待60秒再检查一遍,所以我永远不会停留在那里有一个情况等待previous之一完成的线程队列。

What I want to happen is - if the processing requires more than 60 seconds, than the timer will notice the thread is locked, and wait another 60 seconds to check again so I will never get stuck in a situation where there are a queue of threads waiting for the previous one to finish.

我怎样才能做到这一点的结果?结果
什么是最好的做法这样做呢?

How can i accomplish this result ?
What is the best practice for doing this ?

谢谢!

推荐答案

您可以尝试在加工过程中禁止定时器,像

You might try disabling the timer during processing, something like

// Just in case someone wants to inherit your class and lock it as well ...
private static object _padlock = new object();
try
{
  serviceTimer.Stop(); 

  lock (_padlock)
    { 
        // do some heavy processing... 
    } 
}
finally
{
  serviceTimer.Start(); 
}

修改:OP没有说明是否重入只由定时器或服务是否是多线程引起的。假设以后的,但如果如果定时器停止(自动复位或手动),前者则锁定应该是不必要的。

Edit : OP didn't specify whether the reentrancy was caused only by the timer or whether the service was multi threaded. Have assumed the later, but if the former then locking should be unnecessary if the timer is stopped (AutoReset or manually)

这篇关于如何让计时器滴答跳过如果previous线程仍然忙的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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