Search code examples
c#language-featuressyntactic-sugar

Is there a syntactic sugar in C# similar to `using()` except for taking waiting and releasing on a semaphore?


using (var foo = bar){} is excellent syntactic sugar. It replaces an entire blob

var foo = bar
try
{
}
finally
{
    foo.dispose()
}

I found myself today writing very similar blobs

var foo.WaitOne();
try
{
}
finally
{
    foo.release()
}

I don't suppose there is similar sugar for this in C#?


Solution

  • 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.