带有计时器的worker类确保只调用一次方法

时间:2016-02-29 19:11:15

标签: c#

我目前正在使用这种初步方法:

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当时只能由一个进程运行。

1 个答案:

答案 0 :(得分:1)

您可以使用DoWork方法启动/停止计时器:

private void DoWork(object sender, EventArgs e)
{
    _timer.Stop();

   // .. do stuff ...

    _timer.Start();
}

注意:根据您使用的Timer课程,您可能没有StartStop,而是需要使用Modify方法,但是这个想法。

<强>更新

因此,根据评论,这是一个解决方案,可以防止DoWork执行两次事件,无论Interval属性如何。

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调用。