private static void ReapTasks(TestContext context, TaskContainer container) { if (!container.JoinAll(JoinBeforeAbortTimeout)) { LogMessageAboutActiveTasks(context, container, String.Format("Some tasks failed to complete within {0} seconds of test termination: ", JoinBeforeAbortTimeout.TotalSeconds)); container.AbortAll(); if (!container.JoinAll(JoinAfterAbortTimeout)) { LogMessageAboutActiveTasks(context, container, String.Format("Some tasks failed to abort within {0} seconds of test termination: ", (JoinBeforeAbortTimeout + JoinAfterAbortTimeout).TotalSeconds)); } } }
/// <inheritdoc /> protected override void DecorateTest(IPatternScope scope, ICodeElementInfo codeElement) { scope.TestBuilder.TestInstanceActions.RunTestInstanceBodyChain.Around((state, inner) => { TaskContainer container = new TaskContainer(); try { TestOutcome[] threadOutcomes = new TestOutcome[numThreads]; TestContext context = TestContext.CurrentContext; for (int i = 0; i < numThreads; i++) { int index = i; string name = String.Format("Threaded Repetition #{0}", index + 1); var task = new TestEnvironmentAwareThreadTask(name, delegate { TestContext threadContext = TestStep.RunStep(name, delegate { TestOutcome innerOutcome = inner(state); if (innerOutcome.Status != TestStatus.Passed) { throw new SilentTestException(innerOutcome); } }, null, false, codeElement); threadOutcomes[index] = threadContext.Outcome; }, null); task.Terminated += delegate { if (!task.Result.HasValue) { threadOutcomes[index] = TestOutcome.Error; context.LogWriter.Default.WriteException(task.Result.Exception, String.Format("An exception occurred while starting Threaded Repetition #{0}.", index)); } }; container.Watch(task); task.Start(); } container.JoinAll(null); TestOutcome outcome = TestOutcome.Passed; int passedCount = 0; foreach (TestOutcome threadOutcome in threadOutcomes) { outcome = outcome.CombineWith(threadOutcome); if (threadOutcome.Status == TestStatus.Passed) { passedCount += 1; } } context.LogWriter.Default.WriteLine(String.Format("{0} of {1} threaded repetitions passed.", passedCount, numThreads)); return(outcome); } finally { container.AbortAll(); container.JoinAll(null); } }); }