public void CancelWorkflowApp() { // Arrange TestTrace.Arrange(); var spinExecuting = new AutoResetEvent(false); var completed = new AutoResetEvent(false); var notify = new SpinNotify { LoopComplete = (loops, iterations) => spinExecuting.Set() }; var activity = CreateSequenceWithSpinWaiter(typeof(SpinWaiter)); WorkflowApplicationCompletedEventArgs completedArgs = null; var workflowApplication = new WorkflowApplication(activity) { Completed = args => { completedArgs = args; WorkflowTrace.Verbose( "Completed state: {0} fault {1}", args.CompletionState, args.TerminationException); completed.Set(); }, Aborted = args => WorkflowTrace.Verbose("Aborted {0}", args.Reason), }; var source = new CancellationTokenSource(Constants.Timeout); var tracking = new ListTrackingParticipant(); workflowApplication.Extensions.Add(tracking); workflowApplication.Extensions.Add(notify); var activitySource = new ActivityCancellationToken(source.Token); workflowApplication.Extensions.Add(activitySource); try { // Act TestTrace.Act(); workflowApplication.Run(); TestTrace.Write("Waiting for AsyncSpinWaiter to start executing"); var spinWait = spinExecuting.WaitOne(TimeSpan.FromSeconds(10)); if (spinWait) { source.Token.Register(workflowApplication.Cancel); TestTrace.Write("Cancelling workflow"); source.Cancel(); // workflow.Cancel(); } else { TestTrace.Write("spinWait timeout"); } var isComplete = completed.WaitOne(Constants.Timeout); // Assert TestTrace.Assert(); Assert.IsTrue(isComplete); Assert.IsNotNull(completedArgs); Assert.AreEqual(ActivityInstanceState.Canceled, completedArgs.CompletionState); } finally { TestTrace.Finally(); tracking.Trace(); } }
/// <summary> /// Executes the spin wait /// </summary> /// <param name="token"> /// The token. /// </param> /// <param name="notify"> /// The notify. /// </param> private void DoSpinWait(ActivityCancellationToken token, SpinNotify notify) { for (var i = 0; i < this.Loops; i++) { WorkflowTrace.Verbose( "AsyncSpinWaiter loop {0} of {1}, spinning {2} iterations", i, this.Loops, this.Iterations); try { // For the token cancel if (token.IsCancellationRequested()) { WorkflowTrace.Verbose("Token requests cancel"); return; } Thread.SpinWait(this.Iterations); } finally { if (notify != null) { notify.LoopComplete(this.Loops, this.Iterations); } } } WorkflowTrace.Verbose("AsyncSpinWaiter done with {0} iterations", this.Iterations * this.Loops); }