예제 #1
0
        /// <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);
        }
예제 #2
0
        /// <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);
            }
        }
예제 #4
0
 public void Dispose()
 {
     BaseDisposableWrapper.Dispose();
 }