计时器线程是否等待,直到回调函数中的所有步骤都完成,或者回调函数是否在每个周期中重新调用

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()函数

Jim*_*hel 7

我假设你正在使用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秒.

对于我所做的大多数事情,我展示的第一种技术似乎效果更好.