带计时器的 worker 类可确保该方法仅调用一次
本文关键字:调用 一次 方法 计时器 worker 确保 | 更新日期: 2023-09-27 18:36:50
我目前正在使用这种初步方法:
public class AskingForWorkClass
{
private static Timer _timer;
public void Start()
{
// catchup with outstanding work
DoWork(this, null);
_timer = new Timer { Interval = 1000 }; // one second
_timer.Elapsed += DoWork;
_timer.Start();
}
private void DoWork(object sender, EventArgs e)
{
}
}
目的是在调用 Start 时首先完成所有未完成的工作。之后,使用计时器调用 DoWork,它会检查更多工作。请注意,如果 DoWork 从计时器的最后一次调用开始仍在运行,我想防止 DoWork 被计时器击中。这可能吗?基本上,DoWork一次只能由一个进程运行。
您可以在DoWork
方法中启动/停止计时器:
private void DoWork(object sender, EventArgs e)
{
_timer.Stop();
// .. do stuff ...
_timer.Start();
}
注意:根据您使用的Timer
类,您可能没有Start
和Stop
,而是需要使用Modify
方法,但您明白了。
更新
因此,根据注释,这是一个解决方案,无论Interval
属性如何,它都应该防止任何DoWork
执行两次的事件。
public class AskingForWorkClass
{
private static Timer _timer;
private AutoResetEvent _event = new AutoResetEvent(true);
public void Start()
{
// catchup with outstanding work
DoWork(this, null);
_timer = new Timer { Interval = 1000 }; // one second
_timer.Elapsed += DoWork;
_timer.Start();
}
private void DoWork(object sender, EventArgs e)
{
_event.WaitOne();
// ... do stuff here ...
_event.Set();
}
}
这里发生的情况是,当输入DoWork
时,它将等到事件设置为信号状态并阻止当前线程,直到发生这种情况。 请注意,事件new AutoResetEvent(true)
的构造会在信号状态下创建事件,因此第一次调用DoWork
时不会永远阻塞。
一旦WaitOne
调用通过,事件会自动将自身设置回无信号状态,这意味着将来对 DoWork
方法的调用将被阻止。 最后,我们调用 Set
方法,该方法将事件放回信号状态,直到下一次WaitOne
调用。