public void IdlePersistenceModeShouldSave() { Assert.IsFalse(IdlePersistenceModeExtensions.ShouldSave(IdlePersistenceMode.Never, WorkflowInstanceState.Aborted, isStarting: false)); Assert.IsFalse(IdlePersistenceModeExtensions.ShouldSave(IdlePersistenceMode.Never, WorkflowInstanceState.Runnable, isStarting: false)); Assert.IsFalse(IdlePersistenceModeExtensions.ShouldSave(IdlePersistenceMode.Never, WorkflowInstanceState.Idle, isStarting: false)); Assert.IsFalse(IdlePersistenceModeExtensions.ShouldSave(IdlePersistenceMode.Never, WorkflowInstanceState.Idle, isStarting: true)); Assert.IsFalse(IdlePersistenceModeExtensions.ShouldSave(IdlePersistenceMode.Never, WorkflowInstanceState.Complete, isStarting: false)); Assert.IsFalse(IdlePersistenceModeExtensions.ShouldSave(IdlePersistenceMode.OnCompleted, WorkflowInstanceState.Aborted, isStarting: false)); Assert.IsFalse(IdlePersistenceModeExtensions.ShouldSave(IdlePersistenceMode.OnCompleted, WorkflowInstanceState.Runnable, isStarting: false)); Assert.IsFalse(IdlePersistenceModeExtensions.ShouldSave(IdlePersistenceMode.OnCompleted, WorkflowInstanceState.Idle, isStarting: false)); Assert.IsFalse(IdlePersistenceModeExtensions.ShouldSave(IdlePersistenceMode.OnCompleted, WorkflowInstanceState.Idle, isStarting: true)); Assert.IsTrue(IdlePersistenceModeExtensions.ShouldSave(IdlePersistenceMode.OnCompleted, WorkflowInstanceState.Complete, isStarting: false)); Assert.IsFalse(IdlePersistenceModeExtensions.ShouldSave(IdlePersistenceMode.OnPersistableIdle, WorkflowInstanceState.Aborted, isStarting: false)); Assert.IsFalse(IdlePersistenceModeExtensions.ShouldSave(IdlePersistenceMode.OnPersistableIdle, WorkflowInstanceState.Runnable, isStarting: false)); Assert.IsFalse(IdlePersistenceModeExtensions.ShouldSave(IdlePersistenceMode.OnPersistableIdle, WorkflowInstanceState.Idle, isStarting: true)); Assert.IsTrue(IdlePersistenceModeExtensions.ShouldSave(IdlePersistenceMode.OnPersistableIdle, WorkflowInstanceState.Idle, isStarting: false)); Assert.IsFalse(IdlePersistenceModeExtensions.ShouldSave(IdlePersistenceMode.OnPersistableIdle, WorkflowInstanceState.Complete, isStarting: false)); Assert.IsFalse(IdlePersistenceModeExtensions.ShouldSave(IdlePersistenceMode.OnStart, WorkflowInstanceState.Aborted, isStarting: false)); Assert.IsFalse(IdlePersistenceModeExtensions.ShouldSave(IdlePersistenceMode.OnStart, WorkflowInstanceState.Runnable, isStarting: false)); Assert.IsTrue(IdlePersistenceModeExtensions.ShouldSave(IdlePersistenceMode.OnStart, WorkflowInstanceState.Idle, isStarting: true)); Assert.IsFalse(IdlePersistenceModeExtensions.ShouldSave(IdlePersistenceMode.OnStart, WorkflowInstanceState.Idle, isStarting: false)); Assert.IsFalse(IdlePersistenceModeExtensions.ShouldSave(IdlePersistenceMode.OnStart, WorkflowInstanceState.Complete, isStarting: false)); }
// The TAP async version of OnNotifyPaused() above. protected async Task OnNotifyPausedAsync() { var workflowInstanceState = this.Controller.State; if (workflowInstanceState == WorkflowInstanceState.Aborted) { // If there were a OnRequestAbort() previously, notify the host now. if (this.onRequestAbortReason != null) { await NotifyHostOnUnhandledExceptionAsync(this.onRequestAbortReason, null); } } else { try { // If it's completed, call OnCompletedAsync() on host. if (workflowInstanceState == WorkflowInstanceState.Complete && !this.hasRaisedCompleted) { await IfHasPendingThenFlushTrackingRecordsAsync(); var completionState = this.Controller.GetCompletionState(out var outputs, out var terminationException); await this.host.OnCompletedAsync(completionState, outputs, terminationException); this.hasRaisedCompleted = true; } // Call OnPausedAsync() on INotificationParticipant extensions. await OnPausedAsync(); // Track the Idle state. if (workflowInstanceState == WorkflowInstanceState.Idle && this.Controller.TrackingEnabled) { this.Controller.Track(new WorkflowInstanceRecord(this.Id, this.WorkflowDefinition.DisplayName, System.Activities.Tracking.WorkflowInstanceStates.Idle, this.DefinitionIdentity)); await IfHasPendingThenFlushTrackingRecordsAsync(); } // If required, save state. if (this.Controller.IsPersistable) { if (IdlePersistenceModeExtensions.ShouldSave(this.Parameters.IdlePersistenceMode, workflowInstanceState, this.IsStarting)) { await SaveAsync(); } this.IsStarting = false; } } catch (Exception e) { // Notify host, this can be eg. a serialization exception! await NotifyHostOnUnhandledExceptionAsync(e, null); // TODO Do we really need to protect againts exceptions below? Theoretically Controller won't throw now. // The instance will abort, independently from the configuration. await ExecuteWithExceptionTrackingAsync(() => { return(AbortAsync(e)); }); workflowInstanceState = this.Controller.State; } } // finally // TODO Do we really need to protect againts exceptions below? Theoretically Controller won't throw now. await ExecuteWithExceptionTrackingAsync(() => { // At this point it is possible, that Cancel/Teminate was called by OnNotifyUnhandledException() or OnNotifyPaused(), // and controller/executor Run() should be called, in this case we won't set the reset event, // the Run() will result a callback to OnNotifyPaused() or OnNotifyUnhandledException() again. if (workflowInstanceState == WorkflowInstanceState.Runnable) { return(RunAsync()); } else { this.host.OnNotifyIdle(); return(TaskConstants.Completed); } }); }