我有一个Windows服务,其中包装了WCF服务,后者包装了WorkflowApplication,并调用了活动。 WCF客户端包含在针对给定服务器调用的PowerShell命令中。端到端工作流完美执行,如下所示:
Get-PingResponse -Server 192.168.0.252 -Target 8.8.8.8
Workflow 33d9bd45-663a-4f95-b487-cf2f63081881 completed. Result: True
但是,我认为由于Activity / WorkflowApplication在轮询间隔达到之前完成(最小运行间隔不能小于1秒),因此WorkflowApplication孤立了更新SQL条目。
33D9BD45-663A-4F95-B487-CF2F63081881 NULL 2019-02-07 10:57:43.880 2019-02-07 10:57:43.867 NULL NULL NULL NULL KALLIX Executing 1 0 0 1 NULL NULL 0x1F8B0800000000000400B5565D6FDB36149DF2D1D84ED2A50186ED69308ABD6CB32539F26780CCCCB26E3096A4811DA4018A7AA5242AE52C912E49D955860143036CF909C9D37EE4FEC02859921B0746822AB55F04823CF7DE73CEBD24281C313A444C60C4412EFE0EC0D35F5170025D1F1D41CC9E3BA787D0439004C7C11091C383F1F8E410B6173AF6FBF652B874F55F2FE00279EA1E755D64094C09577F4104316CA91F22BDDE7AF932DE7AEAB9EA3E266FD508BB549C592E154F10E31268A7AAEAE1BF54DCF35DE133B443902F18744BC523DF74B125F18FE900911DB3D18035AB56AFB48C2AD29BAD57A524D673F3779955A9E8718B32179B0F01FEAA9DDBE51C79A61BFC95FBF18D10C36D4DE3D61BE441AEDA50408B1299A62554CACEB42D5DAF6A7A439BCF535EC1DFC628E3F1581D1BC9B98A767AB0DF8B80CB9870018985F2CAB93113D2C316A39C3A42B5A817C633B48AAEF5A404D0C5E730D444038B031484BA5D2EB4577F96B95116497AB501B7438593DD88C5BA7E3DA38A3AB32BA5E0AA3BB3F30128CE2BB03153E45DBC26A6024B44961355BA1897B21E27D8130C93B30FC5FBECFAA73F7C46B663F1CA299365C9E4767C6C57BA7A84C32ED1A421B561DA347FBEA06CE0B874AC80E551D83151D4A538EA77B78EAB5D9F08EC2135460C9EBD43962F9598A674757CEBD447D069544CC768D6EAD036EA5564D4C0469269C74632053171C272AE7537C9D249FA5662DE291552A17B1CBEE1FCE9E1FE54A347D76B4752948491FECA68D2FB11952BD72BBA5A0947800236D312E246E8D819D2BFFEC630EC9669576BE57ADD80E5AAD3AA95CD6AB351B69C2DA76EE8CD4AB3590105986A1F2594CB10127C99F698DD896BD8C75CF00839DF5EEAE173F45EF2BA7BB72873784D0CD62F267C26810EE0504DBEC3A051CC022870C9BD8B3A7280472BABB1779FDE7261EAD904E5537BF63E4CCFA1017C3165FA1919614689276D1F55B8761FDC399EEFE75D6A45E374A2D9FA44B3CBE5BC627E7C33FC96DB8F51D54582DDBF958758501490377D1EEC51397232947C011670963EBB00CB742C1F0311F78F332472734C801CF74D791F0A940572B38B387547E1F861677E6811AEF40B69EBD851D29FFFAB843FB06A523AF0201B1C9C4DAAD9C8101A3C22E89DE8D8170A78EC422E92A6CA34D32EC01AA334C56A2F769173B93A3155865CA593C2EBD1F6DD58C62719C0C0BA831917E12C4F87CE663C747EB83D74E65D98DF4F6E4ED495F5A658D317C927B9441F66326FC4374A90487E4326A5FF15436F7DCC10EF059E49DDC8A17EF882FB27B2A1F23F5068CE26B50B0000 NULL PingActivity NULL 0 0 1 0
在原理/理论上,由于调用了WorkflowApplication.Completed,因此它应向该特定实例的SQL记录发出更新信号;但是,这似乎没有发生-正如记录的状态(如上)所示。
最终目标是-最终-更新记录以反映工作流程的状态。记录的SQL行中的所有状态均未更改,因此所有执行都仅显示“正在执行”,即使对于错误的工作流也是如此。
以前,我在Persistance上将一个条目写入SQL表时遇到问题,这可以通过在WorkflowApplication上调用Persist()来解决。参见here。
SqlWorkflowInstanceStore newSqlWorkflowInstanceStore = new SqlWorkflowInstanceStore("Server=.\\SQL2008EXPRESS;Initial Catalog=WorkflowInstanceStore;Integrated Security=SSPI")
{
HostLockRenewalPeriod = TimeSpan.FromSeconds(5),
InstanceCompletionAction = InstanceCompletionAction.DeleteNothing,
InstanceLockedExceptionAction = InstanceLockedExceptionAction.AggressiveRetry,
RunnableInstancesDetectionPeriod = TimeSpan.FromSeconds(1) // Minimum allowed value.
};
InstanceHandle workflowInstanceStoreHandle = newSqlWorkflowInstanceStore.CreateInstanceHandle();
CreateWorkflowOwnerCommand createWorkflowOwnerCommand = new CreateWorkflowOwnerCommand();
InstanceView newInstanceView = newSqlWorkflowInstanceStore.Execute(workflowInstanceStoreHandle, createWorkflowOwnerCommand, TimeSpan.FromSeconds(30));
newSqlWorkflowInstanceStore.DefaultInstanceOwner = newInstanceView.InstanceOwner;
// The Dictionary will throw for non-found key before we ever get here, so no need to validate input.
WorkflowIdentity newWorkflowIdentity = new WorkflowIdentity
{
Name = command,
Version = new Version(0, 1, 0, 0)
};
// Now stage the WorkflowApplication, using the SQL instance.
AutoResetEvent syncEvent = new AutoResetEvent(false);
WorkflowApplication newWorkflowApplication = new WorkflowApplication(newSwedishCodeActivity, newWorkflowIdentity)
{
InstanceStore = newSqlWorkflowInstanceStore
};
newWorkflowApplication.Persist();
this.Result = new object();
newWorkflowApplication.Completed += delegate(WorkflowApplicationCompletedEventArgs e)
{
if (e.CompletionState == ActivityInstanceState.Faulted)
{
this.Result = $"Workflow {e.InstanceId} has faulted.\nException: {e.TerminationException.GetType().FullName}\nMessage:{e.TerminationException.Message}";
syncEvent.Set();
}
else if (e.CompletionState == ActivityInstanceState.Canceled)
{
this.Result = $"Workflow {e.InstanceId} has been canceled.";
syncEvent.Set();
}
else
{
this.Result = $"Workflow {e.InstanceId} completed. Result: {e.Outputs["Result"]}";
syncEvent.Set();
}
};
newWorkflowApplication.Aborted = delegate(WorkflowApplicationAbortedEventArgs e)
{
// The workflow aborted, so let's find out why.
this.Result = $"Workflow {e.InstanceId} has been aborted.\nException: {e.Reason.GetType().FullName}\nMessage:{e.Reason.Message}";
syncEvent.Set();
};
newWorkflowApplication.Idle = delegate(WorkflowApplicationIdleEventArgs e)
{
this.Result = $"Workflow {e.InstanceId} has entered the Idle state.";
syncEvent.Set();
};
newWorkflowApplication.PersistableIdle = delegate(WorkflowApplicationIdleEventArgs e)
{
this.Result = $"Workflow {e.InstanceId} has entered PersistableIdle.";
syncEvent.Set();
// Runtime will persist.
return PersistableIdleAction.Persist;
};
newWorkflowApplication.Unloaded = delegate(WorkflowApplicationEventArgs e)
{
syncEvent.Set();
};
newWorkflowApplication.OnUnhandledException = delegate(WorkflowApplicationUnhandledExceptionEventArgs e)
{
// Display the unhandled exception.
this.Result = $"Workflow {e.InstanceId} has reached OnUnhandledException.\nException Source: {e.ExceptionSource.DisplayName}\nException Instance ID: {e.ExceptionSourceInstanceId}\nException: {e.UnhandledException.GetType().FullName}\nMessage: {e.UnhandledException.Message}";
syncEvent.Set();
// Instruct the runtime to terminate the workflow.
// The other viable choices here are 'Abort' or 'Cancel'
return UnhandledExceptionAction.Terminate;
};
newWorkflowApplication.Run();
syncEvent.WaitOne();
DeleteWorkflowOwnerCommand newDeleteWorkflowOwnerCommand = new DeleteWorkflowOwnerCommand();
newSqlWorkflowInstanceStore.Execute(
workflowInstanceStoreHandle,
newDeleteWorkflowOwnerCommand,
TimeSpan.FromSeconds(30));
预期结果是,当为WorkflowApplication.Completed调用委托时,它应该向InstanceStore发出信号以更新实例的SQL记录。
实际结果是记录被孤立,并处于“正在执行”状态。
答案 0 :(得分:1)
找到了答案:必须卸载工作流实例,以便在SQL记录中更新状态。
newWorkflowApplication.Unload(TimeSpan.FromSeconds(30));
如果有人遇到此问题,请留在这里。