Reputation: 483
I have a part of code in an Async/Await function that I only want one thread to execute at a time.
This is relatively simple by creating a new SemaphoreSlim(1) and using WaitAsync/Release. The effect is that the first thread executes while the others wait and then execute one by one.
What I am trying to achieve is actually slightly different. I would like the other threads not to wait, but to return out of the function (i.e. I don't want to block the other threads). So if there was a property "NumberOfThreadsCurrentlyExecuting" I would effectively have an If Semaphore.NumberOfThreadsCurrentlyExecuting > 0 Then Return.
But such a property doesn't exist. Does anyone have any idea for a way around this problem?
Thanks Charles
Upvotes: 15
Views: 8086
Reputation: 10600
How about using the SemaphoreSlim.Wait/Async
with a zero-timeout? If it can't enter the semaphore (because it's already been entered), it will return false.
Monitor
(and thus lock
) is completely unsuited to async
(hence the fact that you can't await
in a lock
) because
Upvotes: 40
Reputation: 564333
Instead of a Semaphore, you could just use a Monitor
.
If you call TryEnter
and it fails, another thread is in the "lock".
This is thread safe (unlike checking semaphore counts), and fairly simple:
// using somethign like: object sync = new object();
bool lockTaken = Monitor.TryEnter(sync);
try
{
if (lockTaken)
{
// You're here - do your work
}
else
{
// Something else was in the thread - exit?
return;
}
}
finally
{
if (lockTaken) Monitor.Exit(sync);
}
Upvotes: -3