public void RunCanBeCalledRepeatedly()
        {
            ThreadAbortScope scope = new ThreadAbortScope();
            int count = 0;

            for (int i = 0; i < 3; i++)
            {
                Assert.IsNull(scope.Run(delegate { count += 1; }));
            }

            Assert.AreEqual(3, count);
        }
        public void RunThrowsIfCalledReentrantlyOnSameThread()
        {
            ThreadAbortScope scope = new ThreadAbortScope();

            scope.Run(delegate
            {
                Assert.Throws<InvalidOperationException>(delegate
                {
                    scope.Run(delegate { });
                });
            });
        }
        public void RunThrowsIfCalledReentrantlyOnDifferentThread()
        {
            ThreadAbortScope scope = new ThreadAbortScope();

            scope.Run(delegate
            {
                Tasks.StartThreadTask("Reentrant Call to Scope.Run", () =>
                {
                    Assert.Throws<InvalidOperationException>(delegate
                    {
                        scope.Run(delegate { });
                    });
                });
                Tasks.JoinAndVerify(TimeSpan.FromMilliseconds(500));
            });
        }
        public void AbortBeforeRunCausesImmediateAbortion()
        {
            ThreadAbortScope scope = new ThreadAbortScope();
            int count = 0;

            scope.Abort();
            Assert.IsNotNull(scope.Run(delegate { count += 1; }));

            Assert.AreEqual(0, count);
        }
        public void AbortWaitsUntilProtectedScopeEndsBeforeOccurring()
        {
            ThreadAbortScope scope = new ThreadAbortScope();

            ManualResetEvent barrier = new ManualResetEvent(false);
            Tasks.StartThreadTask("Background Abort", delegate
            {
                barrier.WaitOne();
                scope.Abort();
            });

            int count = 0;
            Assert.IsNotNull(scope.Run(delegate
            {
                count += 1;

                using (scope.Protect())
                {
                    count += 1;
                    barrier.Set();
                    Thread.Sleep(5000);
                    count += 1;
                }

                count += 1; // should not run
            }));

            Assert.AreEqual(3, count);

            Tasks.JoinAndVerify(TimeSpan.FromMilliseconds(100));
        }
        public void RunThrowsIfActionIsNull()
        {
            ThreadAbortScope scope = new ThreadAbortScope();

            scope.Run(null);
        }
        public void ProtectInAnotherThreadJustRunsTheAction()
        {
            ThreadAbortScope scope = new ThreadAbortScope();

            bool ran = false;

            Tasks.StartThreadTask("Different thread", () =>
            {
                using (scope.Protect())
                    ran = true;
            });
            Tasks.JoinAndVerify(TimeSpan.FromMilliseconds(100));

            Assert.IsTrue(ran, "Should have run the action.");
        }
Beispiel #8
0
        public TestOutcome Run(MarkupDocumentWriter markupDocumentWriter, Action action, string description)
        {
            // NOTE: This method has been optimized to minimize the total stack depth of the action
            //       by inlining blocks on the critical path that had previously been factored out.

            if (markupDocumentWriter == null)
                throw new ArgumentNullException("markupDocumentWriter");
            if (action == null)
                throw new ArgumentNullException("action");

            ThreadAbortScope scope = null;
            try
            {
                lock (syncRoot)
                {
                    ThrowIfDisposed();

                    if (!abortOutcome.HasValue)
                    {
                        if (scopesAndThreads == null)
                            scopesAndThreads = new List<Pair<ThreadAbortScope, Thread>>();

                        scope = new ThreadAbortScope();
                        scopesAndThreads.Add(new Pair<ThreadAbortScope, Thread>(scope, Thread.CurrentThread));
                    }
                }

                if (scope == null)
                    return HandleAbort(markupDocumentWriter, description, null);

                // Run the action within the scope we have acquired.
                try
                {
                    ThreadAbortException ex = scope.Run(action);
                    if (ex != null)
                        return HandleAbort(markupDocumentWriter, description, ex);

                    return TestOutcome.Passed;
                }
                catch (Exception ex)
                {
                    // If the test itself threw a thread abort, not because we aborted it
                    // ourselves but most likely due to a bug in the test subject, then we
                    // prevent the abort from bubbling up any further.
                    if (ex is ThreadAbortException &&
                        !AppDomain.CurrentDomain.IsFinalizingForUnload())
                        Thread.ResetAbort();

                    TestOutcome outcome;
                    TestException testException = ex as TestException;
                    if (testException != null)
                    {
                        outcome = testException.Outcome;

                        if (testException.ExcludeStackTrace)
                            LogMessage(markupDocumentWriter, description, outcome, testException.HasNonDefaultMessage ? testException.Message : null, null);
                        else
                            LogMessage(markupDocumentWriter, description, outcome, null, testException);
                    }
                    else
                    {
                        outcome = TestOutcome.Failed;
                        LogMessage(markupDocumentWriter, description, outcome, null, ex);
                    }

                    return outcome;
                }
            }
            finally
            {
                if (scope != null)
                {
                    lock (syncRoot)
                    {
                        if (scopesAndThreads != null)
                        {
                            for (int i = 0; i < scopesAndThreads.Count; i++)
                                if (scopesAndThreads[i].First == scope)
                                    scopesAndThreads.RemoveAt(i);
                        }
                    }
                }
            }
        }
        public void TryToAsynchronouslyHitARunningActionAtRandomTimes()
        {
            const int Iterations = 50;
            Random random = new Random(0);

            for (int i = 0; i < Iterations; i++)
            {
                ThreadAbortScope scope = new ThreadAbortScope();

                Tasks.StartThreadTask("Background Abort", delegate
                {
                    Thread.Sleep(random.Next(5));
                    scope.Abort();
                });

                Stopwatch timeout = Stopwatch.StartNew();
                while (scope.Run(delegate { Thread.SpinWait(1000); }) == null)
                {
                    if (timeout.ElapsedMilliseconds > 500)
                        Assert.Fail("The scope failed to stop the run during iteration {0}.", i);
                }

                Tasks.JoinAndVerify(TimeSpan.FromMilliseconds(100));
            }
        }
        public void ProtectOutsideOfScopeJustRunsTheAction()
        {
            ThreadAbortScope scope = new ThreadAbortScope();

            bool ran = false;
            using (scope.Protect())
                ran = true;

            Assert.IsTrue(ran, "Should have run the action.");
        }
        public void AbortFromADifferentSourceUnwindsGracefully()
        {
            ThreadAbortScope outerScope = new ThreadAbortScope();

            Assert.IsNotNull(outerScope.Run(delegate
            {
                ThreadAbortScope innerScope = new ThreadAbortScope();
                innerScope.Run(delegate { outerScope.Abort(); });
            }));
        }
        public void AbortFromADifferentThreadUnwindsGracefully()
        {
            ThreadAbortScope scope = new ThreadAbortScope();

            ManualResetEvent barrier = new ManualResetEvent(false);
            Tasks.StartThreadTask("Background Abort", delegate
            {
                barrier.WaitOne();
                scope.Abort(); 
            });

            int count = 0;
            Assert.IsNotNull(scope.Run(delegate
            {
                count += 1;
                barrier.Set();
                Thread.Sleep(5000);

                count += 1; // should not run
            }));

            Assert.AreEqual(1, count);

            Tasks.JoinAndVerify(TimeSpan.FromMilliseconds(100));
        }
        public void AbortDuringRunOnSameThreadUnwindsGracefully()
        {
            ThreadAbortScope scope = new ThreadAbortScope();

            int count = 0;
            Assert.IsNotNull(scope.Run(delegate
            {
                count += 1;
                scope.Abort();
                count += 1;
            }));

            Assert.AreEqual(1, count);
        }
        public void AbortAfterRunCausesImmediateAbortionOfNextRun()
        {
            ThreadAbortScope scope = new ThreadAbortScope();

            int count = 0;
            Assert.IsNull(scope.Run(delegate { count += 1; }));

            scope.Abort();
            Assert.IsNotNull(scope.Run(delegate { count += 1; }));

            Assert.AreEqual(1, count);
        }
        public void AbortFromWithinProtectedScopeDoesNotOccurUntilTheProtectedScopeExits()
        {
            bool ranToCompletion = false;
            ThreadAbortScope scope = new ThreadAbortScope();
            ThreadAbortException ex = scope.Run(() =>
            {
                using (scope.Protect())
                {
                    scope.Abort();
                    ranToCompletion = true;
                }
            });

            Assert.IsNotNull(ex, "Should have aborted.");
            Assert.IsTrue(ranToCompletion, "Should have run the action.");
        }
Beispiel #16
0
 public ResetToRunningState(ThreadAbortScope scope)
 {
     this.scope = scope;
 }
 public ResetToRunningState(ThreadAbortScope scope)
 {
     this.scope = scope;
 }