如何以原子方式检查并重置超时?

时间:2017-09-28 18:41:12

标签: c# multithreading

我有一个检查某个超时时间是否已过期的方法,如果有,则重置开始时间并返回true:

bool CheckAndResetTimeout() {
    if (DateTime.UtcNow > _start + _timeout) {
        _start = DateTime.UtcNow;
        return true;
    }
    return false;
}

如果两个线程同时击中它,我怎么能使这个线程安全?保证只返回true一次?我认为这可以通过双重检查锁定来实现,但我希望在BCL中找到一些东西(最有可能在System.Threading下),这可能为此提供更高级别的抽象。

2 个答案:

答案 0 :(得分:3)

您可以使用lock关键字:

static object TimerLock = new object();
static bool CheckAndResetTimeout()
{
    lock (TimerLock)
    {
        if (DateTime.UtcNow > _start + _timeout)
        {
            _start = DateTime.UtcNow;
            return true;
        }
        return false;
    }
}

https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/lock-statement

答案 1 :(得分:1)

如果可能的话,我希望避免使用lock,例如通过编写来自Sysetm.Threading.Interlocked的轻量级构造,但我还没有想出一个很好的方法来做到这一点。所以现在我正在做double-checked locking,这至少可以避免lock开销大多数

private readonly object _timeoutLock = new object();

public bool CheckAndResetTimeout() {
    if (DateTime.UtcNow > _start + _timeout) {
        lock (_timeoutLock) {
            if (DateTime.UtcNow > _start + _timeout) {
                _start = DateTime.UtcNow;
                return true;
            }
        }
    }
    return false;
}