public void TestCancelAfter_TimerReset()
        {
            TimeSpan initialTimeout = TimeSpan.FromSeconds(0.10);
            TimeSpan updatedTimeout = TimeSpan.FromSeconds(0.35);

            CancellationTokenSource cts = new CancellationTokenSource();
            Stopwatch timer             = Stopwatch.StartNew();

            CancellationTokenSourceExtensions.CancelAfter(cts, initialTimeout);
            CancellationTokenSourceExtensions.CancelAfter(cts, updatedTimeout);

            // a task which never completes
            Task[] tasks = { new TaskCompletionSource <object>().Task };

            try
            {
                Task.WaitAll(tasks, cts.Token);
                Assert.Fail("The CancellationTokenSource failed to cancel.");
            }
            catch (OperationCanceledException)
            {
                TimeSpan elapsed = timer.Elapsed;
                Assert.IsTrue(elapsed >= updatedTimeout - AdvanceTolerance, "The CancellationTokenSource canceled too soon ({0} sec < {1} sec).", elapsed.TotalSeconds, (updatedTimeout - AdvanceTolerance).TotalSeconds);
                Assert.IsTrue(elapsed <= updatedTimeout + DelayTolerance, "The CancellationTokenSource canceled too late ({0} sec > {1} sec).", elapsed.TotalSeconds, (updatedTimeout + DelayTolerance).TotalSeconds);
            }
        }
        public void TestCancelAfter_TimerPinning()
        {
            TimeSpan timeout = TimeSpan.FromSeconds(0.40);

            CancellationTokenSource cts = new CancellationTokenSource();
            Stopwatch timer             = Stopwatch.StartNew();

            CancellationTokenSourceExtensions.CancelAfter(cts, timeout);

            GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
            GC.WaitForFullGCComplete();

            // a task which never completes
            Task[] tasks = { new TaskCompletionSource <object>().Task };

            try
            {
                Task.WaitAll(tasks, cts.Token);
                Assert.Fail("The CancellationTokenSource failed to cancel.");
            }
            catch (OperationCanceledException)
            {
                // The specific time of cancellation is not relevant to this test.
            }
        }
        public void TestCancelAfter_TimerPinning()
        {
            TimeSpan timeout = TimeSpan.FromSeconds(0.40);
            TimeSpan tolerance = TimeSpan.FromSeconds(0.025);

            CancellationTokenSource cts = new CancellationTokenSource();
            Stopwatch timer = Stopwatch.StartNew();
            CancellationTokenSourceExtensions.CancelAfter(cts, timeout);

            GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, true);

            // a task which never completes
            Task[] tasks = { new TaskCompletionSource<object>().Task };

            try
            {
                Task.WaitAll(tasks, cts.Token);
                Assert.Fail("The CancellationTokenSource failed to cancel.");
            }
            catch (OperationCanceledException)
            {
                TimeSpan elapsed = timer.Elapsed;
                Assert.IsTrue(elapsed >= timeout - tolerance, "The CancellationTokenSource cancelled too soon ({0} sec < {1} sec).", elapsed.TotalSeconds, (timeout - tolerance).TotalSeconds);
                Assert.IsTrue(elapsed <= timeout + tolerance, "The CancellationTokenSource cancelled too late ({0} sec > {1} sec).", elapsed.TotalSeconds, (timeout + tolerance).TotalSeconds);
            }
        }
        public void TestCancelAfter_GCEligible()
        {
            CancellationTokenSource cts = new CancellationTokenSource();
            WeakReference weakReference = new WeakReference(cts);
            CancellationTokenSourceExtensions.CancelAfter(cts, TimeSpan.FromHours(1));

            Assert.IsNotNull(weakReference.Target);

            GC.KeepAlive(cts);
            cts = null;
            GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, true);

            Assert.IsNull(weakReference.Target);
        }
 public void TestCancelAfter_ArgumentOutOfRange()
 {
     CancellationTokenSourceExtensions.CancelAfter(new CancellationTokenSource(), TimeSpan.FromSeconds(-1));
 }
 public void TestCancelAfter_ArgumentNull()
 {
     CancellationTokenSourceExtensions.CancelAfter(null, TimeSpan.FromSeconds(1));
 }