首先,我对WorkFlow Foundation 4.5完全不熟悉。我们使用WF引擎来管理Case实体中的状态。我们决定使用WF,而不是建立我们自己的状态机。主要是因为我们的客户有大量的流程(并不复杂),我们想用xaml绘制。每个人都很容易理解这个过程并谈论它。
问题是我们转换到结束状态Final状态导致StateMachineStateTracker实例在加载时为null。下面的代码适用于所有转换,我们可以在恢复书签后加载跟踪器实例,以查看新的当前状态。
private void ConfigureWorkflowApplication(WorkflowApplication wfApp, SqlWorkflowInstanceStore store)
{
wfApp.InstanceStore = store;
var tracker = new StateMachineStateTracker(wfApp.WorkflowDefinition);
wfApp.Extensions.Add(tracker);
wfApp.Extensions.Add(new StateTrackerPersistenceProvider(tracker));
wfApp.Completed = delegate { Debug.WriteLine("Workflow completed."); };
wfApp.Aborted =
delegate(WorkflowApplicationAbortedEventArgs e)
{
Debug.WriteLine("Workflow Aborted. Exception: {0}\r\n{1}", e.Reason.GetType().FullName,
e.Reason.Message);
};
wfApp.OnUnhandledException = delegate(WorkflowApplicationUnhandledExceptionEventArgs e)
{
Debug.WriteLine("Unhandled Exception: {0}\r\n{1}", e.UnhandledException.GetType().FullName,
e.UnhandledException.Message);
return UnhandledExceptionAction.Terminate;
};
wfApp.PersistableIdle = delegate { return PersistableIdleAction.Unload; };
}
上面的代码实例化一个WorkFlowApplication实例。
protected bool执行(活动进程,Case @case,字符串转换) { WorkflowApplicationInstance instance = null; 使用(var store = new DisposableStore()) { instance = WorkflowApplication.GetInstance(@ case.InstanceId,store.Store);
var wfApp = new WorkflowApplication(process, WorkflowIdentity);
ConfigureWorkflowApplication(wfApp, store.Store);
var trackerInstance = StateMachineStateTracker.LoadInstance(@case.InstanceId, wfApp.WorkflowDefinition,
_connectionString);
if (!trackerInstance.Transitions.Any(x => x.DisplayName.Equals(transition))) return false;
}
using (var store = new DisposableStore())
{
var wfApp = new WorkflowApplication(process, instance.DefinitionIdentity);
ConfigureWorkflowApplication(wfApp, store.Store);
wfApp.Load(@case.InstanceId);
var sync = new AutoResetEvent(false);
wfApp.ResumeBookmark(transition, null);
wfApp.Unloaded = x => sync.Set();
sync.WaitOne();
// Set case to new state
var trackerInstance = StateMachineStateTracker.LoadInstance(@case.InstanceId, wfApp.WorkflowDefinition,
_connectionString);
@case.ChangeToNewState(trackerInstance.CurrentState);
}
return true;
}
上面的代码有意从一个状态转换到下一个状态(字符串转换),我们还想将新状态设置为Case类。
当我们想要在最终状态之前从我们的州执行此操作时,这会失败。没有例外。无记录输出窗口。没有。只是那行
var trackerInstance = StateMachineStateTracker.LoadInstance(@ case.InstanceId,wfApp.WorkflowDefinition, _connectionString);
返回null。这是因为您无法使用处于最终状态的实例加载StateMachineStateTracker(不确定它是否实际到达最终状态)。
有人对此问题有任何疑问吗?我觉得这是我们忘记的基本内容。
答案 0 :(得分:1)
确定。我发现了这个问题。就像我一样。不是问题。只是我在WF的新秀。 当您转换到最终状态时,WF会在完成后删除有关案例的所有数据。这意味着SurrogateInstance已从DB中删除,状态机状态跟踪器当然无法正常工作,因为无法加载到跟踪器中。 但是我在WorkflowApplication的Completed事件上做了一个委托方法,它可以处理闭包并完成我们的案例。
wfApp.Completed = delegate(WorkflowApplicationCompletedEventArgs e)
{
Debug.WriteLine("Workflow completed.");
Debug.WriteLine("State" + e.CompletionState);
if (e.CompletionState == ActivityInstanceState.Closed)
{
_caseIsCompleted = true;
}
};