Reputation: 39319
I have a method that checks whether some timeout period has expired, and if it has, resets the start time and returns true:
bool CheckAndResetTimeout() {
if (DateTime.UtcNow > _start + _timeout) {
_start = DateTime.UtcNow;
return true;
}
return false;
}
How can I make this thread safe in the sense that if 2 threads hit it at the same time, it is guaranteed to only return true once? I think this can be achieved via double-check locking, but I was hoping to find something in the BCLs (under System.Threading
most likely) that might provide a higher-level abstraction for this.
Upvotes: 0
Views: 131
Reputation: 39319
I hoped to avoid a lock
if possible, such as by composing lighter-weight constructs from Sysetm.Threading.Interlocked
, but I haven't come up with a good way to do that. So for now I'm doing double-checked locking, which at least avoids the lock
overhead most of the time.
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;
}
Upvotes: 1
Reputation: 12815
You can use the lock
keyword for this:
static object TimerLock = new object();
static bool CheckAndResetTimeout()
{
lock (TimerLock)
{
if (DateTime.UtcNow > _start + _timeout)
{
_start = DateTime.UtcNow;
return true;
}
return false;
}
}
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/lock-statement
Upvotes: 3