带计时器的 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一次只能由一个进程运行。

带计时器的 worker 类可确保该方法仅调用一次

您可以在DoWork方法中启动/停止计时器:

private void DoWork(object sender, EventArgs e)
{
    _timer.Stop();
   // .. do stuff ...
    _timer.Start();
}

注意:根据您使用的Timer类,您可能没有StartStop,而是需要使用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调用。