C# 停机联锁保护例行程序
我的计时器例程受多入口保护,如下所示:C# 停机联锁保护例行程序,c#,C#,我的计时器例程受多入口保护,如下所示: private void TimerCallback(object state) { if (Interlocked.CompareExchange(ref currentlyRunningTasksCount, 1, 0) != 0) { return; } // some job is being done here Interlocked.Decrement(ref currentlyRun
private void TimerCallback(object state)
{
if (Interlocked.CompareExchange(ref currentlyRunningTasksCount, 1, 0) != 0)
{
return;
}
// some job is being done here
Interlocked.Decrement(ref currentlyRunningTasksCount);
}
<>也有定时器关机程序,我想确保计时器不在某个中间。因此,我做了以下工作:
public void Shutdown()
{
aTimer.Change(Timeout.Infinite, Timeout.Infinite);
for(;;)
{
if (Interlocked.CompareExchange(ref currentlyRunningTasksCount, 0, 0) == 0)
{
break;
}
else
{
Thread.Sleep(1000);
continue;
}
}
}
问题-检查关机是否正确,或者我应该使用
联锁。阅读并与0比较?我会使用锁。它可以轻松地支持这两种情况,无需等待
如果(!Monitor.TryEnter(…)返回,则可以使用
退出勾号处理程序
要等待计时器退出,请执行锁定(…){}
您需要设置一个布尔字段来表示计时器已关闭。调用Change
后,可以触发任意多个勾号事件。(出于同样的原因,您现有的关闭代码实际上并没有关闭计时器。)
尽管如此,所有这些都可以简化:
async Task RunMyTimerAgent() {
while (true) {
await Task.Delay(...);
Work();
ThrowIfCancelled();
}
}
var timer = RunMyTimerAgent();
//cancel the timer here
timer.Wait(); //Wait till shutdown.
不过,这个循环有时间漂移。lock
更容易理解。。。此外,创建能够被最少人阅读/理解的代码可能是OP的全部要点:)。顺便说一句,我认为在任务的循环中。延迟对于固定时间漂移来说更为明显,因为人们可以每次调整延迟(不像通常以固定延迟和漂移运行的常规计时器)。对不起,而应该取代什么?当前关闭程序?你能详细说明一下这个机制吗?while会取代整个定时器。如何修正漂移?我觉得这种方法非常简单有趣。@ScottChamberlain我推荐TickCount。DateTime.UtcNow可以任意更改,并导致循环基本停止或提前执行。微软推动在BCL中用UtcNow替换各种内部超时。我想它发生在4.5。