As adviced by Alexei, your best chance is to mock the requested behavior using an helper class which implements IDisposable
.
Something like this should suffice:
public static class AutoReleaseSemaphoreExtensions
{
// single threaded + idempotent Dispose version
private sealed class AutoReleaseSemaphore : IDisposable
{
private readonly Semaphore _semaphore;
private bool _disposed = false;
public AutoReleaseSemaphore(Semaphore semaphore)
{
_semaphore = semaphore;
}
public void Dispose()
{
if(_disposed) return;
_semaphore.Release();
_disposed = true;
}
}
public static IDisposable WaitOneAndRelease(this Semaphore semaphore)
{
semaphore.WaitOne();
return new AutoReleaseSemaphore(semaphore);
}
}
Which may be used in the following way (thanks to extension methods):
var sem = new Semaphore(0, 1); // your semaphore here
using (sem.WaitOneAndRelease())
{
// do work here
}
// semaphore is released outside using block.