C# 如何以原子方式检查和重置超时?

C# 如何以原子方式检查和重置超时?,c#,multithreading,C#,Multithreading,我有一个方法可以检查某个超时是否已过期,如果已过期,则重置开始时间并返回true: bool CheckAndResetTimeout() { if (DateTime.UtcNow > _start + _timeout) { _start = DateTime.UtcNow; return true; } return false; } 如果两个线程同时命中该线程,它将保证只返回true一次,那么如何使该线程安全呢?我认为这可以

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

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

如果两个线程同时命中该线程,它将保证只返回true一次,那么如何使该线程安全呢?我认为这可以通过双重检查锁定来实现,但我希望在BCLs中(最有可能的是在
系统.线程
下)找到可以提供更高级别抽象的东西。

您可以使用
锁定
关键字:

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

您可以使用
锁定
关键字:

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

如果可能的话,我希望避免使用
锁,比如从中编写更轻量级的结构,但我还没有想出一个好方法来做到这一点。所以现在我正在做,这至少避免了大部分时间的
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;
}

如果可能的话,我希望避免使用
,比如从中编写更轻量级的构造,但我还没有想出一个好方法来做到这一点。所以现在我正在做,这至少避免了大部分时间的
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;
}

你为什么不用一个真正的计时器呢?这将在内部为您处理这个问题-当间隔时间过去时,您将得到一个回调。因为我希望它是懒惰的。如果超时已经过期,调用它的东西负责做一些工作,我不想让那些工作比必要的时候做得更频繁。我不确定我是否理解。计时器只是为您提供了一种跟踪已用时间的方法(在您的示例中就是这样做的)。如果您希望您的调用者避免调用此函数过于频繁,那么您的调用者应该有一个计时器。然后你可以有一个标志(由锁保护),你可以检查工作是否已经在进行。为什么不使用一个实际的计时器呢?这将在内部为您处理这个问题-当间隔时间过去时,您将得到一个回调。因为我希望它是懒惰的。如果超时已经过期,调用它的东西负责做一些工作,我不想让那些工作比必要的时候做得更频繁。我不确定我是否理解。计时器只是为您提供了一种跟踪已用时间的方法(在您的示例中就是这样做的)。如果您希望您的调用者避免调用此函数过于频繁,那么您的调用者应该有一个计时器。然后,您可以使用一个标志(由锁保护)来检查工作是否已在进行。我希望尽可能避免使用
,例如从
Sysetm.Threading.Interlocked
组合结构,这些结构的重量要轻得多。尽管我还没有想出一个方法来解决这个问题。尽管我希望有一个比我自己更好的答案,但这是我采用的解决方案,因为双重检查在避免锁开销方面有很大的不同,所以我将其标记为已接受+我建议您使用锁,这似乎很公平,因为我确实使用了锁。:)我希望尽可能避免使用
,比如从
Sysetm.Threading.Interlocked
组合结构,这些结构重量要轻得多。尽管我还没有想出一个方法来解决这个问题。尽管我希望有一个比我自己更好的答案,但这是我采用的解决方案,因为双重检查在避免锁开销方面有很大的不同,所以我将其标记为已接受+我建议您使用锁,这似乎很公平,因为我确实使用了锁。:)