关闭互锁保护程序

时间:2016-06-09 15:16:09

标签: c#

我的计时器例程受到多入口保护,如下所示:

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;
        }
    }
}

问题 - 检查关机是否正确,或者我应该使用Interlock.Read并与0比较?

1 个答案:

答案 0 :(得分:4)

我会使用锁。它可以轻松地支持这两种情况,而无需繁忙等待。

您可以使用lock (...) { }退出代码处理程序。

要等待计时器退出,请执行Change

您需要设置一个布尔字段来表示定时器已关闭。 对Shutdown的调用后,可以发出任意多个滴答事件。 (出于同样的原因,您现有的async Task RunMyTimerAgent() { while (true) { await Task.Delay(...); Work(); ThrowIfCancelled(); } } var timer = RunMyTimerAgent(); //cancel the timer here timer.Wait(); //Wait till shutdown. 代码实际上并没有关闭计时器。)

但所有这一切都可以简化:

cert_key_file  = <cert_key_file>
cert_key_password = 'xxx'

client = Savon.client do |globals|
  globals.log true
  globals.wsdl "#{Rails.root}/wsdl/<-wsdl->"
  globals.ssl_cert_file cert_key_file
  globals.ssl_ca_cert_file cert_key_file
  globals.ssl_cert_key_file cert_key_file
  globals.ssl_cert_key_password cert_key_password
  globals.ssl_verify_mode :none
  globals.ssl_version :SSLv3
end

client.call(:function_to_call, message: function_to_call_body(data))
enter code here

但是这个循环有时间漂移。