我有一个检查某个超时时间是否已过期的方法,如果有,则重置开始时间并返回true:
bool CheckAndResetTimeout() {
if (DateTime.UtcNow > _start + _timeout) {
_start = DateTime.UtcNow;
return true;
}
return false;
}
如果两个线程同时击中它,我怎么能使这个线程安全?保证只返回true一次?我认为这可以通过双重检查锁定来实现,但我希望在BCL中找到一些东西(最有可能在System.Threading
下),这可能为此提供更高级别的抽象。
答案 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;
}