I have read the docs for SemaphoreSlim SemaphoreSlim MSDN which indicates that the SemaphoreSlim will limit a section of code to be run by only 1 thread at a time if you configu
From the documentation:
The SemaphoreSlim class doesn’t enforce thread or task identity on calls to the Wait, WaitAsync, and Release methods
In other words, the class doesn't look to see which thread is calling it. It's just a simple counter. The same thread can acquire the semaphore multiple times, and that will be the same as if multiple threads acquired the semaphore. If the thread count remaining is down to 0, then even if a thread already was one that had acquired the semaphore that thread, if it calls Wait()
, it will block until some other thread releases the semaphore.
So, with respect to async
/await
, the fact that an await
may or may not resume in the same thread where it was started doesn't matter. As long as you keep your Wait()
and Release()
calls balanced, it will work as one would hope and expect.
In your example, you're even waiting on the semaphore asynchronously, and thus not blocking any thread. Which is good, because otherwise you'd deadlock the UI thread the second time you pressed your button.
Related reading:
Resource locking between iterations of the main thread (Async/Await)
Why does this code not end in a deadlock
Locking with nested async calls
Note in particular caveats on re-entrant/recursive locking, especially with async
/await
. Thread synchronization is tricky enough as it is, and that difficulty is what async
/await
is designed to simplify. And it does so significantly in most cases. But not when you mix it with yet another synchronization/locking mechanism.