public static void RunContinueWithPreCancelTests_State() { Action <Task, bool, string> EnsureCompletionStatus = delegate(Task task, bool shouldBeCompleted, string message) { if (task.IsCompleted != shouldBeCompleted) { Assert.True(false, string.Format(string.Format("RunContinueWithPreCancelTests_State: > FAILED. {0}.", message))); } }; CancellationTokenSource cts = new CancellationTokenSource(); cts.Cancel(); ManualResetEvent mres = new ManualResetEvent(false); // Pre-increment the dontCounts for pre-canceled continuations to make final check easier // (i.e., all counts should be 1 at end). int[] doneCount = { 0, 0, 1, 0, 1, 0 }; string stateParam = "test"; //used as a state parametr for the continuation if the useStateParam is true Task t1 = new Task(delegate { doneCount[0]++; }); Task c1 = t1.ContinueWith((_, obj) => { doneCount[1]++; }, stateParam); Task c2 = c1.ContinueWith((_, obj) => { mres.WaitOne(); doneCount[2]++; }, stateParam, cts.Token); Task c3 = c2.ContinueWith((_, obj) => { mres.WaitOne(); doneCount[3]++; }, stateParam); Task c4 = c3.ContinueWith((_, obj) => { mres.WaitOne(); doneCount[4]++; }, stateParam, cts.Token, TaskContinuationOptions.LazyCancellation, TaskScheduler.Default); Task c5 = c4.ContinueWith((_, obj) => { mres.WaitOne(); doneCount[5]++; }, stateParam); EnsureCompletionStatus(c2, true, " c2 should have completed (canceled) upon construction"); EnsureCompletionStatus(c4, false, " c4 should NOT have completed (canceled) upon construction"); EnsureCompletionStatus(t1, false, " t1 should NOT have completed before being started"); EnsureCompletionStatus(c1, false, " c1 should NOT have completed before antecedent completed"); EnsureCompletionStatus(c3, false, " c3 should NOT have completed before mres was set"); EnsureCompletionStatus(c5, false, " c5 should NOT have completed before mres was set"); // These should be done already. And Faulted. Exception exception = null; try { c2.Wait(); Assert.True(false, string.Format("RunContinueWithPreCancelTests_State: Expected c2.Wait to throw AE/TCE")); } catch (Exception ex) { exception = ex; } EnsureExceptionIsAEofTCE(exception, "RunContinueWithPreCancelTests_State: Expected c2.Wait to throw AE/TCE"); mres.Set(); Debug.WriteLine("RunContinueWithPreCancelTests_State: Waiting for tasks to complete... if we hang here, something went wrong."); c3.Wait(); try { c4.Wait(); Assert.True(false, string.Format("RunContinueWithPreCancelTests_State: Expected c4.Wait to throw AE/TCE")); } catch (Exception ex) { exception = ex; } EnsureExceptionIsAEofTCE(exception, "RunContinueWithPreCancelTests_State: Expected c4.Wait to throw AE/TCE"); c5.Wait(); EnsureCompletionStatus(t1, false, " t1 should NOT have completed (post-mres.Set()) before being started"); EnsureCompletionStatus(c1, false, " c1 should NOT have completed (post-mres.Set()) before antecedent completed"); t1.Start(); c1.Wait(); for (int i = 0; i < 6; i++) { if (doneCount[i] != 1) { Assert.True(false, string.Format("RunContinueWithPreCancelTests_State: > FAILED. doneCount[{0}] should be 1, is {1}", i, doneCount[i])); } } }
public static Task <IEnumerable <TResult> > AsIEnumerable <TResult>(this Task <TResult[]> task) { return(task.ContinueWith(t => t.Result as IEnumerable <TResult>)); }