// Renamed to conform to Microsoft's guidelines. public static async Task <Sync> AcquireAsync(TimeSpan releaseAfter) { var sync = new Sync(); await Semaphore.WaitAsync().ConfigureAwait(false); try { return(sync); } finally { // Fire-and-forget, not awaited. sync.DelayedRelease(releaseAfter); } }
public static async Task <Sync> Acquire(TimeSpan releaseAfter) { // State = -1: Disposing sync won't release the semaphore. var sync = new Sync(); await Semaphore.WaitAsync().ConfigureAwait(false); try { // State = 0: Call to sync.Dispose() will release the semaphore // unless it has already transisioned to State = 1 via ReleaseOnce by then. sync.State = 0; return(sync); } finally { // Not awaited. sync.DelayedRelease(releaseAfter); } }
public static async Task <Sync> AcquireAsync(TimeSpan releaseAfter) { // State = -1: Disposing sync won't release the semaphore. // In case we are unable to enter the semaphore the newly // created Sync instance won't call Release unnecessarily // when disposed. var sync = new Sync(); await Semaphore.WaitAsync().ConfigureAwait(false); try { // State = 0: from here on sync.Dispose will call // Semaphore.Release (until the Sync instance has // transisions to State = 1 via ReleaseOnce). sync.State = 0; return(sync); } finally { // Not awaited. sync.DelayedRelease(releaseAfter); } }