Beispiel #1
0
        public static bool ExternalCancel_GetConsumingEnumerable()
        {
            TestHarness.TestLog("* BlockingCollectionCancellationTests.ExternalCancel_GetConsumingEnumerable()");
            bool passed = true;

            BlockingCollection <int> bc = new BlockingCollection <int>();
            CancellationTokenSource  cs = new CancellationTokenSource();

            ThreadPool.QueueUserWorkItem(
                (obj) =>
            {
                Thread.Sleep(100);
                cs.Cancel();
            });

            IEnumerable <int> enumerable = bc.GetConsumingEnumerable(cs.Token);

            passed &= TestHarnessAssert.IsFalse(cs.IsCancellationRequested, "At this point the cancel should not have occurred.");
            passed &= TestHarnessAssert.EnsureOperationCanceledExceptionThrown(
                () => enumerable.GetEnumerator().MoveNext(),
                cs.Token,
                "The operation should wake up via token cancellation.");

            return(passed);
        }
Beispiel #2
0
        public static bool ExternalCancel_TryAddToAny()
        {
            TestHarness.TestLog("* BlockingCollectionCancellationTests.ExternalCancel_AddToAny()");
            bool passed = true;

            BlockingCollection <int> bc1 = new BlockingCollection <int>(1);
            BlockingCollection <int> bc2 = new BlockingCollection <int>(1);

            bc1.Add(1); //fill the bc.
            bc2.Add(1); //fill the bc.

            CancellationTokenSource cs = new CancellationTokenSource();

            ThreadPool.QueueUserWorkItem(
                (obj) =>
            {
                Thread.Sleep(100);
                cs.Cancel();
            });

            passed &= TestHarnessAssert.IsFalse(cs.IsCancellationRequested, "At this point the cancel should not have occurred.");
            passed &= TestHarnessAssert.EnsureOperationCanceledExceptionThrown(
                () => BlockingCollection <int> .TryAddToAny(new[] { bc1, bc2 }, 1, 10000, cs.Token),
                cs.Token,
                "The operation should wake up via token cancellation.");

            return(passed);
        }
Beispiel #3
0
        public static bool ExternalCancel_TryTake()
        {
            TestHarness.TestLog("* BlockingCollectionCancellationTests.ExternalCancel_TryTake()");
            bool passed = true;

            BlockingCollection <int> bc = new BlockingCollection <int>(); //empty collection.

            CancellationTokenSource cs = new CancellationTokenSource();

            ThreadPool.QueueUserWorkItem(
                (obj) =>
            {
                Thread.Sleep(100);
                cs.Cancel();
            });

            int item;

            passed &= TestHarnessAssert.IsFalse(cs.IsCancellationRequested, "At this point the cancel should not have occurred.");
            passed &= TestHarnessAssert.EnsureOperationCanceledExceptionThrown(
                () => bc.TryTake(out item, 100000, cs.Token),
                cs.Token,
                "The operation should wake up via token cancellation.");

            return(passed);
        }
Beispiel #4
0
        //This tests that Take/TryTake wake up correctly if CompleteAdding() is called while the taker is waiting.
        public static bool InternalCancellation_WakingUpTake()
        {
            TestHarness.TestLog("* BlockingCollectionCancellationTests.InternalCancellation_WakingUpTake()");
            bool passed = true;

            BlockingCollection <int> coll1 = new BlockingCollection <int>();

            ThreadPool.QueueUserWorkItem(
                (obj) =>
            {
                Thread.Sleep(500);
                coll1.CompleteAdding();
            });

            //call Take.. it should wake up with an OCE. when CompleteAdding() is called.
            passed &= TestHarnessAssert.IsFalse(coll1.IsAddingCompleted, "(1) At this point CompleteAdding should not have occurred.");
            passed &= TestHarnessAssert.EnsureExceptionThrown(
                () => coll1.Take(), typeof(InvalidOperationException),
                "an IOE should be thrown if CompleteAdding occurs during blocking Take()");

            return(passed);
        }
Beispiel #5
0
        //This tests that Take/TryTake wake up correctly if CompleteAdding() is called while the taker is waiting.
        public static bool InternalCancellation_WakingUpTryTake()
        {
            TestHarness.TestLog("* BlockingCollectionCancellationTests.InternalCancellation_WakingUpTryTake()");
            bool passed = true;

            BlockingCollection <int> coll1 = new BlockingCollection <int>();

            ThreadPool.QueueUserWorkItem(
                (obj) =>
            {
                Thread.Sleep(500);
                coll1.CompleteAdding();
            });

            int item;

            passed &= TestHarnessAssert.IsFalse(coll1.IsAddingCompleted, "At this point CompleteAdding should not have occurred.");
            bool tookItem = coll1.TryTake(out item, 1000000); // wait essentially indefinitely. 1000seconds.

            passed &= TestHarnessAssert.IsFalse(tookItem, "TryTake should wake up with tookItem=false.");

            return(passed);
        }
Beispiel #6
0
        //This tests that TryAdd wake up correctly if CompleteAdding() is called while the taker is waiting.
        public static bool InternalCancellation_WakingUpTryAdd()
        {
            TestHarness.TestLog("* BlockingCollectionCancellationTests.InternalCancellation_WakingUpTryAdd()");
            bool passed = true;

            BlockingCollection <int> coll1 = new BlockingCollection <int>(1);

            coll1.Add(1); //fills the collection.

            ThreadPool.QueueUserWorkItem(
                (obj) =>
            {
                Thread.Sleep(500);
                coll1.CompleteAdding();
            });

            passed &= TestHarnessAssert.IsFalse(coll1.IsAddingCompleted, "At this point CompleteAdding should not have occurred.");
            passed &= TestHarnessAssert.EnsureExceptionThrown(
                () => coll1.TryAdd(1, 1000000),  //an indefinite wait to add.. 1000 seconds.
                typeof(InvalidOperationException),
                "an InvalidOpEx should be thrown if CompleteAdding occurs during blocking Add()");

            return(passed);
        }
Beispiel #7
0
        //Identified as a possible concern in bug 544743.
        private static bool SemaphoreSlim_MultipleWaitersWithSeparateTokens()
        {
            TestHarness.TestLog("* SemaphoreSlimCancellationTests.SemaphoreSlim_MultipleWaitersWithSeparateTokens()");
            bool passed = true;

            SemaphoreSlim semaphoreSlim                = new SemaphoreSlim(0); // this semaphore will always be blocked for waiters.
            const int     waitTimeoutMilliseconds      = 1000;
            const int     waitBeforeCancelMilliseconds = 300;

            CancellationTokenSource cts1        = new CancellationTokenSource();
            CancellationTokenSource cts2        = new CancellationTokenSource();
            bool wait1WokeUpNormally            = false;
            bool wait2WokeUpNormally            = false;
            OperationCanceledException wait1OCE = null;
            OperationCanceledException wait2OCE = null;
            int wait1ElapsedMilliseconds        = -1;
            int wait2ElapsedMilliseconds        = -1;

            CountdownEvent cde_allThreadsFinished = new CountdownEvent(2);

            //Queue up cancellation of CTS1.
            ThreadPool.QueueUserWorkItem(
                unused =>
            {
                Thread.Sleep(waitBeforeCancelMilliseconds);     // wait a little while.
                cts1.Cancel();
            }
                );

            //Queue up a wait on mres(CTS1)
            ThreadPool.QueueUserWorkItem(
                unused =>
            {
                Stopwatch sw = Stopwatch.StartNew();
                try
                {
                    wait1WokeUpNormally = semaphoreSlim.Wait(waitTimeoutMilliseconds, cts1.Token);
                }
                catch (OperationCanceledException oce)
                {
                    wait1OCE = oce;
                }
                finally
                {
                    sw.Stop();
                }
                wait1ElapsedMilliseconds = (int)sw.Elapsed.TotalMilliseconds;

                cde_allThreadsFinished.Signal();
            }
                );

            //Queue up a wait on mres(CTS2)
            ThreadPool.QueueUserWorkItem(
                unused =>
            {
                Stopwatch sw = Stopwatch.StartNew();
                try
                {
                    wait2WokeUpNormally = semaphoreSlim.Wait(waitTimeoutMilliseconds, cts2.Token);
                }
                catch (OperationCanceledException oce)
                {
                    wait2OCE = oce;
                }
                finally
                {
                    sw.Stop();
                }
                wait2ElapsedMilliseconds = (int)sw.Elapsed.TotalMilliseconds;
                cde_allThreadsFinished.Signal();
            }
                );

            cde_allThreadsFinished.Wait();

            Console.WriteLine("        (first  wait duration [expecting <={0,4}]        ={1,4})", 500, wait1ElapsedMilliseconds);
            Console.WriteLine("        (second wait duration [expecting   {0,4} +-50ms] ={1,4})", waitTimeoutMilliseconds, wait2ElapsedMilliseconds);

            passed &= TestHarnessAssert.IsFalse(wait1WokeUpNormally, "The first wait should be canceled.");
            passed &= TestHarnessAssert.IsNotNull(wait1OCE, "The first wait should have thrown an OCE.");
            passed &= TestHarnessAssert.AreEqual(cts1.Token, OCEHelper.ExtractCT(wait1OCE), "The first wait should have thrown an OCE(cts1.token).");
            passed &= TestHarnessAssert.IsTrue(wait1ElapsedMilliseconds < 500, "[Warning: Timing Sensitive Test] The first wait should have canceled before 500ms elapsed.");


            passed &= TestHarnessAssert.IsFalse(wait2WokeUpNormally, "The second wait should not have woken up normally. It should have woken due to timeout.");
            passed &= TestHarnessAssert.IsNull(wait2OCE, "The second wait should not have thrown an OCE.");
            passed &= TestHarnessAssert.IsTrue(950 <= wait2ElapsedMilliseconds && wait2ElapsedMilliseconds <= 1050, "[Warning: Timing Sensitive Test] The second wait should have waited 1000ms +-50ms). Actual wait duration = " + wait2ElapsedMilliseconds);

            return(passed);
        }