internal WaitHandleDistributedSemaphoreHandle(Semaphore semaphore) { this._semaphoreReleaser = new SemaphoreReleaser(semaphore); // We need a managed finalizer here because an abandoned Semaphore instance won't release its tickets unless // all instances of that Semaphore are also abandoned (any one live instance tracks the current ticket count). this._finalizerRegistration = ManagedFinalizerQueue.Instance.Register(this, this._semaphoreReleaser); }
/// <summary> /// Waits to enter the busy lock and returns an IDisposable that will /// update the <see cref="LastActivityTime"/> and release the lock /// when disposed. /// </summary> /// <param name="cancellationToken">Cancellation token to use to cancel waiting.</param> /// <returns><see cref="IDisposable"/> that releases the lock when disposed.</returns> internal async Task <IDisposable> RequestBusyLockAsync(CancellationToken cancellationToken) { await _busyLock.WaitAsync(cancellationToken); try { SemaphoreReleaser releaser = new SemaphoreReleaser(_busyLock); // Set the last activity time to just before the busy lock is released releaser.Releasing += (s, e) => LastActivityTime = DateTime.Now; return(releaser); } catch { // Shouldn't ever happen, but just in case, // if there's an error release here _busyLock.Release(); throw; } }