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

I am currently using this preliminary approach:

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)

{

}

}

The intention is that when Start is invoked all outstanding work is done first. After that a timer is used to invoke DoWork, which checks for more work does it. Please note that I would like to prevent DoWork from being hit by the timer if it is still running from the last invocation by the timer. Is this possible? Basically, DoWork should only be run by one process at the time.

Talk1:

Stop the timer on DoWork and restart before exiting from it...

Solutions1

You can just start / stop the timer in your DoWork method:

private void DoWork(object sender, EventArgs e)

{

_timer.Stop();

// .. do stuff ...

_timer.Start();

}

Note: depending on which Timer class you're using, you may not have Start and Stop and instead need to use the Modify method, but you get the idea.

UPDATE

So based on comments this is a solution which should prevent any incident of DoWork executing twice, regardless of the Interval property.

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();

}

}

What happens here is that that when DoWork is entered it will wait until the event has been set to the signaled state and block the current thread until that happens. Note that the construction of the event new AutoResetEvent(true) creates the event in the signaled state so the first time DoWork is called it doesn't block forever.

Once the WaitOne call passes, the event automatically sets itself back to the unsignaled state meaning that future calls to the DoWork method will be blocked. Then finally we call the Set method which puts the event back into the signaled state until the next WaitOne call.

Talk1:

This still has the possibly of executing twice if the timer interval is small enough. Better to set AutoReset to false and then just call _timer.Start() after DoWork finishes.

Talk2:

Agreed, that's a good thing to note for the OP. But based on his sample code I think this solution is fine and has the advantage of being a bit simpler.

Talk3:

I would prefer it to be as robust as possible (-:

Talk4:

Thanks. Will check out tomorrow.

Talk5:

Just to be clear, I may have overstated the "... regarless of the Interval propery". I can imagine some very edge cases where you could still make it run twice, but I think this is a pretty robust solution.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值