Sha*_*nan 2 c# multithreading timer
我有一个计时器线程功能
SampleTimer = new Timer(SomeTask,0,70000)
Run Code Online (Sandbox Code Playgroud)
回拨功能如下
void SomeTask(object o)
{
//block using autoresetevent
}
Run Code Online (Sandbox Code Playgroud)
问题是SomeTask()回调方法每70秒调用一次,即使回调方法中的所有操作仍未完成.如何防止计时器在其中的所有步骤完成之前调用SomeTask()函数
我假设你正在使用System.Threading.Timer.
一种方法是将计时器创建为一次性,然后在线程完成其任务后重新启动它.这样你就可以确定你不会有任何重叠:
myTimer = new Timer(someMethod, null, 70000, Timeout.Infinite);
Run Code Online (Sandbox Code Playgroud)
在你的回调中:
void TimerCallback(object o)
{
// do stuff here
// then change the timer
myTimer.Change(70000, Timeout.Infinite);
}
Run Code Online (Sandbox Code Playgroud)
指定Timeout.Infinite周期会禁用周期性信号,将定时器转为一次性.
另一种方法是使用监视器:
object TimerLock = new object();
void TimerCallback(object o)
{
if (!Monitor.TryEnter(TimerLock))
{
// already in timer. Exit.
return;
}
// do stuff
// then release the lock
Monitor.Exit(TimerLock);
}
Run Code Online (Sandbox Code Playgroud)
如果您想知道为什么我不使用try/finally锁定,请参阅Eric Lippert的博客,锁定和例外不要混合.
这两种方法的主要区别在于,在前一次回调执行完成后,计时器将在70秒后触发.在第二个定时器将在70秒的周期内启动,因此下一个回调可能会在前一个回复完成后的任何时间执行,从一秒后再到70秒.
对于我所做的大多数事情,我展示的第一种技术似乎效果更好.