예제 #1
0
        // a specific repro where inner queries would see an ODE on the merged cancellation token source
        // when the implementation involved disposing and recreating the token on each worker thread
        private static bool Cancellation_ODEIssue()
        {
            bool passed = true;
            AggregateException caughtException = null;

            try
            {
                Enumerable.Range(0, 1999).ToArray()
                .AsParallel().AsUnordered()
                .WithExecutionMode(ParallelExecutionMode.ForceParallelism)
                .Zip <int, int, int>(
                    Enumerable.Range(1000, 20).Select <int, int>(_item => (int)_item).AsParallel().AsUnordered(),
                    (first, second) => { throw new OperationCanceledException(); })
                .ForAll(x => { });
            }
            catch (AggregateException ae)
            {
                caughtException = ae;
            }

            //the failure was an ODE coming out due to an ephemeral disposed merged cancellation token source.
            passed &= TestHarnessAssert.IsTrue(caughtException != null,
                                               "We expect an aggregate exception with OCEs in it.");

            return(passed);
        }
예제 #2
0
        // After running a plinq query, we expect the internal cancellation token source to have been disposed.
        // The critical thing is that there are no callbacks left hanging on the external tokens callback list, else we
        // could be causing an accumulation of junk that will not GC until the external token goes away (possibly never).
        private static bool Bugfix626345_PlinqShouldDisposeLinkedToken()
        {
            bool passed = true;

            TestHarness.TestLog("* PlinqCancellationTests.Bugfix626345_PlinqShouldDisposeLinkedToken()");

#if DEBUG
            // Only run these in debug mode, because they rely on a debug-only property.
            PropertyInfo callbackCountProperty =
                typeof(CancellationTokenSource).
                GetProperty("CallbackCount", BindingFlags.Instance | BindingFlags.NonPublic);
            if (callbackCountProperty == null)
            {
                TestHarness.TestLog("    - Error: CancellationTokenSource.CallbackCount property not found; was it removed?");
                return(false);
            }
            Func <CancellationTokenSource, int> getCallbackCount =
                _ => (int)callbackCountProperty.GetValue(_, null);

            CancellationTokenSource cts = new CancellationTokenSource();
            CancellationToken       ct  = cts.Token;

            // ForAll
            Enumerable.Range(1, 10).AsParallel().WithCancellation(ct).ForAll((x) => { });
            passed &= TestHarnessAssert.IsTrue(getCallbackCount(cts) == 0, "The callback list should be empty.");

            // Built-in-aggregation
            Enumerable.Range(1, 10).AsParallel().WithCancellation(ct).Average();
            passed &= TestHarnessAssert.IsTrue(getCallbackCount(cts) == 0, "The callback list should be empty.");

            // Manual aggregation
            Enumerable.Range(1, 10).AsParallel().WithCancellation(ct).Aggregate((a, b) => a + b);
            passed &= TestHarnessAssert.IsTrue(getCallbackCount(cts) == 0, "The callback list should be empty.");

            // ToArray  (uses ToList, which enumerates the query with foreach())
            Enumerable.Range(1, 10).AsParallel().WithCancellation(ct).ToArray();
            passed &= TestHarnessAssert.IsTrue(getCallbackCount(cts) == 0, "The callback list should be empty.");

            // AsynchronousChannelMergeEnumerator
            foreach (int x in Enumerable.Range(1, 10).AsParallel().WithCancellation(ct).Select(xx => xx))
            {
            }
            passed &= TestHarnessAssert.IsTrue(getCallbackCount(cts) == 0, "The callback list should be empty.");

            // SynchronousChannelMergeEnumerator
            foreach (int x in Enumerable.Range(1, 10).AsParallel().WithCancellation(ct).WithMergeOptions(ParallelMergeOptions.FullyBuffered))
            {
            }
            passed &= TestHarnessAssert.IsTrue(getCallbackCount(cts) == 0, "The callback list should be empty.");

            // Fallback to sequential
            foreach (int x in Enumerable.Range(1, 10).AsParallel().WithCancellation(ct).Where(xx => true).Skip(4))
            {
            }
            passed &= TestHarnessAssert.IsTrue(getCallbackCount(cts) == 0, "The callback list should be empty.");
#endif

            return(passed);
        }
예제 #3
0
        // Tests that the shared state variable seems to be working correctly.
        private static bool RunManualResetEventSlimTest4_CombinedStateTests()
        {
            bool passed = true;

            TestHarness.TestLog("* RunManualResetEventSlimTest4_CombinedStateTests()");

            ManualResetEventSlim mres = new ManualResetEventSlim(false, 100);
            int expectedCount         = Environment.ProcessorCount == 1 ? 1 : 100;

            passed &= TestHarnessAssert.AreEqual(expectedCount, mres.SpinCount, "Spin count did not write/read correctly, expected " + expectedCount + ", actual " + mres.SpinCount);
            passed &= TestHarnessAssert.IsFalse(mres.IsSet, "Set did not read correctly.");
            mres.Set();
            passed &= TestHarnessAssert.IsTrue(mres.IsSet, "Set did not write/read correctly.");

            return(passed);
        }