private void CreateTask() { _cts = new CancellationTokenSource(); _task = new Task((o) => { _taskThreadID = Environment.CurrentManagedThreadId; switch (_workloadType) { case WorkloadType.CreateChildTask: case WorkloadType.CreateDetachedChildTask: Task.Factory.StartNew(() => { }, _workloadType == WorkloadType.CreateDetachedChildTask ? TaskCreationOptions.None : TaskCreationOptions.AttachedToParent); break; case WorkloadType.ContinueInside: _task.ContinueWith((t) => { }); break; case WorkloadType.RunWithUserScheduler: TaskScheduler ts = new TaskRunSyncTaskScheduler(true); Task.Factory.StartNew(() => { }, _cts.Token, TaskCreationOptions.AttachedToParent, ts).ContinueWith((task) => DisposeScheduler(ts), TaskScheduler.Default); break; case WorkloadType.ThrowException: throw new TPLTestException(); } }, null, _cts.Token, _option); }
/// <summary> /// The main test method that execute the API. There are five steps involved in the execution of the test /// </summary> internal void RealRun() { TaskScheduler ts = TaskScheduler.Default; switch (_taskSchedulerType) { case TaskSchedulerType.Null: ts = null; break; case TaskSchedulerType.CustomWithInlineExecution: ts = new TaskRunSyncTaskScheduler(true); break; case TaskSchedulerType.CustomWithoutInlineExecution: ts = new TaskRunSyncTaskScheduler(false); break; default: ts = TaskScheduler.Default; break; } // Stage 1 -- create task CreateTask(); // Stage 2 - start with the pre-action switch (_preTaskStatus) { case PreTaskStatus.Continued: _task = _task.ContinueWith((t) => { }, _cts.Token, TaskContinuationOptions.None, ts); break; case PreTaskStatus.Running: _task.Start(ts); break; case PreTaskStatus.Canceled: _cts.Cancel(); break; case PreTaskStatus.Completed: _task.Start(ts); ((IAsyncResult)_task).AsyncWaitHandle.WaitOne(); // wait on AsyncWaitHandle to avoid getting exp break; } int expectedThreadID = Environment.CurrentManagedThreadId; // Stage 3 - exercise the API try { if (_taskSchedulerType == TaskSchedulerType.Default) { _task.RunSynchronously(); } else { _task.RunSynchronously(ts); } if (ExpectRunSyncFailure) { Assert.True(false, string.Format("Fail to throw expected InvalidOperationException")); } if (_taskSchedulerType == TaskSchedulerType.Null) { Assert.True(false, string.Format("Fail to throw expected ArgumentNullException")); } } catch (InvalidOperationException ex) { if (!ExpectRunSyncFailure) { Assert.True(false, string.Format("Caught un-expected InvalidOperationException - {0}", ex)); } else { Debug.WriteLine("Caught expected InvalidOperationException"); DisposeScheduler(ts); return; } } catch (ArgumentNullException ex) { if (_taskSchedulerType != TaskSchedulerType.Null) { Assert.True(false, string.Format("Caught un-expected ArgumentNullException - {0}", ex)); } else { Debug.WriteLine("Caught expected ArgumentNullException"); DisposeScheduler(ts); return; } } // Stage 4 - do verification against Context, IsCompleted and the TaskStatus if (_taskSchedulerType == TaskSchedulerType.CustomWithInlineExecution) { Assert.Equal(expectedThreadID, _taskThreadID); } else if (_taskSchedulerType == TaskSchedulerType.CustomWithoutInlineExecution) { Assert.NotEqual(expectedThreadID, _taskThreadID); } else if (_taskThreadID != expectedThreadID) { Debug.WriteLine("Warning: RunSynchronously request ignored -- Task did not run under the same context"); } Assert.True(_task.IsCompleted, "RunSynchronously contract broken -- Task is not complete when the call return"); if (_workloadType == WorkloadType.ThrowException) { if (_task.Status != TaskStatus.Faulted) { Assert.True(false, string.Format("Wrong final task status on a faulty workload")); } CheckExpectedAggregateException(_task.Exception); //Assert.True(false, string.Format("Fail to record the test exception in Task.Exception")); } else { if (_task.Status != TaskStatus.RanToCompletion) { Assert.True(false, string.Format("Wrong final task status on a regular workload")); } } // // Extra verification to ensure the Task was RunSynchronously on // specified TaskScheduler // if (_taskSchedulerType == TaskSchedulerType.CustomWithInlineExecution || _taskSchedulerType == TaskSchedulerType.CustomWithoutInlineExecution) { if (((TaskRunSyncTaskScheduler)ts).RunSyncCalledCount <= 0) { Assert.True(false, string.Format("Task wasn't RunSynchronously with TaskScheduler specified")); } } // Stage 5 - follow with the post-action switch (_postRunSyncAction) { case PostRunSyncAction.Wait: try { if (_postRunSyncAction == PostRunSyncAction.Wait) { _task.Wait(0); } if (_workloadType == WorkloadType.ThrowException) { Assert.True(false, string.Format("expected failure is not propogated out of Wait")); } } catch (AggregateException ae) { CheckExpectedAggregateException(ae); } break; case PostRunSyncAction.Cancel: _cts.Cancel(); break; case PostRunSyncAction.ContinueWith: _task.ContinueWith((t) => { }).Wait(); break; } DisposeScheduler(ts); }
/// <summary> /// The main test method that execute the API. There are five steps involved in the execution of the test /// </summary> internal void RealRun() { TaskScheduler ts = TaskScheduler.Default; switch (_taskSchedulerType) { case TaskSchedulerType.Null: ts = null; break; case TaskSchedulerType.CustomWithInlineExecution: ts = new TaskRunSyncTaskScheduler(true); break; case TaskSchedulerType.CustomWithoutInlineExecution: ts = new TaskRunSyncTaskScheduler(false); break; default: ts = TaskScheduler.Default; break; } // Stage 1 -- create task CreateTask(); // Stage 2 - start with the pre-action switch (_preTaskStatus) { case PreTaskStatus.Continued: _task = _task.ContinueWith((t) => { }, _cts.Token, TaskContinuationOptions.None, ts); break; case PreTaskStatus.Running: _task.Start(ts); break; case PreTaskStatus.Canceled: _cts.Cancel(); break; case PreTaskStatus.Completed: _task.Start(ts); ((IAsyncResult)_task).AsyncWaitHandle.WaitOne(); // wait on AsyncWaitHandle to avoid getting exp break; } int expectedThreadID = Environment.CurrentManagedThreadId; // Stage 3 - exercise the API try { if (_taskSchedulerType == TaskSchedulerType.Default) _task.RunSynchronously(); else _task.RunSynchronously(ts); if (ExpectRunSyncFailure) Assert.True(false, string.Format("Fail to throw expected InvalidOperationException")); if (_taskSchedulerType == TaskSchedulerType.Null) Assert.True(false, string.Format("Fail to throw expected ArgumentNullException")); } catch (InvalidOperationException ex) { if (!ExpectRunSyncFailure) Assert.True(false, string.Format("Caught un-expected InvalidOperationException - {0}", ex)); else { Debug.WriteLine("Caught expected InvalidOperationException"); DisposeScheduler(ts); return; } } catch (ArgumentNullException ex) { if (_taskSchedulerType != TaskSchedulerType.Null) Assert.True(false, string.Format("Caught un-expected ArgumentNullException - {0}", ex)); else { Debug.WriteLine("Caught expected ArgumentNullException"); DisposeScheduler(ts); return; } } // Stage 4 - do verification against Context, IsCompleted and the TaskStatus if (_taskSchedulerType == TaskSchedulerType.CustomWithInlineExecution) Assert.Equal(expectedThreadID, _taskThreadID); else if (_taskSchedulerType == TaskSchedulerType.CustomWithoutInlineExecution) Assert.NotEqual(expectedThreadID, _taskThreadID); else if (_taskThreadID != expectedThreadID) Debug.WriteLine("Warning: RunSynchronously request ignored -- Task did not run under the same context"); Assert.True(_task.IsCompleted, "RunSynchronously contract broken -- Task is not complete when the call return"); if (_workloadType == WorkloadType.ThrowException) { if (_task.Status != TaskStatus.Faulted) Assert.True(false, string.Format("Wrong final task status on a faulty workload")); CheckExpectedAggregateException(_task.Exception); //Assert.True(false, string.Format("Fail to record the test exception in Task.Exception")); } else { if (_task.Status != TaskStatus.RanToCompletion) Assert.True(false, string.Format("Wrong final task status on a regular workload")); } // // Extra verification to ensure the Task was RunSynchronously on // specified TaskScheduler // if (_taskSchedulerType == TaskSchedulerType.CustomWithInlineExecution || _taskSchedulerType == TaskSchedulerType.CustomWithoutInlineExecution) { if (((TaskRunSyncTaskScheduler)ts).RunSyncCalledCount <= 0) Assert.True(false, string.Format("Task wasn't RunSynchronously with TaskScheduler specified")); } // Stage 5 - follow with the post-action switch (_postRunSyncAction) { case PostRunSyncAction.Wait: try { if (_postRunSyncAction == PostRunSyncAction.Wait) _task.Wait(0); if (_workloadType == WorkloadType.ThrowException) Assert.True(false, string.Format("expected failure is not propogated out of Wait")); } catch (AggregateException ae) { CheckExpectedAggregateException(ae); } break; case PostRunSyncAction.Cancel: _cts.Cancel(); break; case PostRunSyncAction.ContinueWith: _task.ContinueWith((t) => { }).Wait(); break; } DisposeScheduler(ts); }