Charles
Charles

Reputation: 483

Skip SemaphoreSlim instead of wait

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

Answers (2)

Mark Sowul
Mark Sowul

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.

Note that Monitor (and thus lock) is completely unsuited to async

(hence the fact that you can't await in a lock) because

  1. your task may continue on another thread after you've entered the lock (thus you will try to release the lock from another thread)
  2. after you've awaited, another continuation may use your thread (while it is still holding the lock), so if it attempts to acquire the lock it will succeed

Upvotes: 40

Reed Copsey
Reed Copsey

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

Related Questions