/// <summary> /// Asynchronously waits for a signal from another thread, aborting if the operation is cancelled /// </summary> /// <param name="token"></param> /// <returns>True, if the operation succeeds. False if the operation is cancelled</returns> public async Task <bool> WaitAsync(CancellationToken token) { //The SyncLock to use SyncLock blocker; //The lock wrapper DisposableWrapper wrapper; //Next acquires the lock for this instance, and enqueues our wrapped lock using (await _sync.GetLockAsync().ConfigureAwait(false)) { //If we have leftover pulses, consume one instead of waiting. if (pulses > 0) { pulses--; return(true); } //Otherwise create the SyncLock blocker = new SyncLock(); //And wrap up a lock from it for eventual release queue.Enqueue(wrapper = new DisposableWrapper(await blocker.GetLockAsync())); } //Finally, waits for the lock, and if we time out, we release it ourselves. //If on the rare chance the lock is released between the time we stop waiting and the time we try to release it, say we were signalled successfully if (!await blocker.TryGetLockAsync(token, l => l.Dispose())) { return(!wrapper.Dispose()); } //say we were signalled successfully. return(true); }
/// <summary> /// Waits for a signal from another thread, aborting if the operation is cancelled /// </summary> /// <param name="token"></param> /// <returns>True, if the operation succeeds. False if the operation is cancelled</returns> public bool Wait(CancellationToken token) { //Create a new lock to wait for SyncLock blocker; //Then acquires the lock and wraps it up in preperation to offering it to the queue DisposableWrapper wrapper; //Next acquires the lock for this instance, and enqueues our wrapped lock using (_sync.GetLock()) { if (pulses > 0) { pulses--; return(true); } blocker = new SyncLock(); queue.Enqueue(wrapper = new DisposableWrapper(blocker.GetLock())); } //Finally, waits for the lock, and if we time out, we release it ourselves. //If on the rare chance the lock is released between the time we stop waiting and the time we try to release it, say we were signalled successfully if (!blocker.TryGetLock(token, out IDisposable @lock)) { return(!wrapper.Dispose()); //Just in case a last minute call lets us return true; } //If we did get a lock however, release that @lock.Dispose(); //Before finally signaling that we were successfuly return(true); }
public void Dispose_ShouldCallGarbageCollectorSuppressFinalize() { using(ShimsContext.Create()) { object suppressFinalizeInstance = null; bool suppressFinalizeIsCalled = false; ShimGC.SuppressFinalizeObject = delegate(object instance) { suppressFinalizeInstance = instance; suppressFinalizeIsCalled = true; }; Assert.IsNull(suppressFinalizeInstance); Assert.IsFalse(suppressFinalizeIsCalled); var disposableWrapper = new DisposableWrapper<IDisposable>(Mock.Of<IDisposable>()); disposableWrapper.Dispose(); Assert.IsNotNull(suppressFinalizeInstance); Assert.IsTrue(ReferenceEquals(disposableWrapper, suppressFinalizeInstance)); Assert.IsTrue(suppressFinalizeIsCalled); } }
public void Dispose() { BaseDisposableWrapper.Dispose(); }