4

我有一组自定义活动,用于复杂的工作流程。

我想让它们(自定义活动)持久化,而无需让工作流处于空闲状态。它应该是一种故障转移系统,因此每当工作流执行期间出现问题时,它可能是:

  • 由用户暂停(随时)并稍后从暂停的书签/点恢复(例如,用户注意到外部系统已关闭,他想暂时暂停工作流程)。
  • 如果出现未处理的异常,我们可以从最后一个书签/时间点重新开始执行
  • WorkflowApplication 主机的停止可以随时发生,我们可以从最后一个书签/时间点重新开始执行

我已经用工作流持久性工作了几天,但我不确定我是否可以用它来实现我的目标。为什么?

  • 我可以在每个自定义活动中使用阻止书签,但是阻止工作流并重新启动它只是为了让它持久化看起来并不乐观。
  • 我可以使用不阻止书签,但我无法在数据库中看到它们并从中恢复。

你能告诉我吗,工作流书签是这里的路吗?

我在不阻止书签方面看到了一些亮点,但我无法保留它们并稍后恢复。您能否给我一些提示,如何为以后的简历保留非阻塞书签?

编辑:

在 wf3 中有一个属性PersistOnClose足以满足我的要求。在 wf4 中,它被替换为Persist活动,这也可能很有用,但是我不想在我已经很复杂的工作流程中进行额外的活动。

理想情况下,能够从 执行会很棒context.RequestPersist(callback)NativeActivityContext但是这个方法是内部的(并且它里面的所有东西在原始程序集之外都是不可见的。

4

2 回答 2

3

这是我带来的:

  • 非阻塞书签不是一种选择。尽管非阻塞书签不会阻止创建活动完成,但它也不会导致工作流实例变得空闲 - 这意味着它不会被持久化。一旦活动(创建它)完成,非阻塞书签将被丢弃。只有在创建活动尚未完成时才能恢复此书签。
  • 使用PersistOnCloseAttribute不是一个选项,因为我使用的是 WF4,而这个属性只有 .NET 3.x WF。
  • 无法使用阻止书签,因为它们会阻止工作流的执行,这是不希望的。

解决方案是Persist在每个自定义活动中使用活动(必须扩展NativeActivity可以安排子活动):

//class field
Activity childActivity = new Persist();

为了使其工作,必须将其作为 ImplmentationChild 添加到元数据中:

protected override void CacheMetadata(NativeActivityMetadata metadata)
{
     base.CacheMetadata(metadata);
     metadata.AddImplementationChild(this.childActivity);
}

最后一件事是从 Execute 方法调度子活动(不管在哪里,只有在调用活动完成后才会发生持久性*)。

protected override void Execute(NativeActivityContext context)
{
    //...
    context.ScheduleActivity((Activity)this.childActivity);
}

为了在未处理的异常后保持工作流持续存在,必须将这段代码添加到 WorkflowApplication:

 application.OnUnhandledException = delegate(WorkflowApplicationUnhandledExceptionEventArgs e)
 {
      return UnhandledExceptionAction.Abort;
 };

*从该Execute方法返回并不一定意味着该活动已“完成” - 即活动内有阻塞书签(请参阅下面的缺点)。

这种解决方案有几个缺点:

  • 解决方案仅保留工作流的一个状态(最后一个状态)。
  • 只有当活动完成时,才会发生持久性。这意味着无法从活动中间完成持久/恢复。
  • 它不适用于并行循环/序列 - 并行循环/序列中的活动在整个并行事物完成后持续存在。它适用于常规循环/序列。
  • 阻止书签对这个解决方案有很大的影响(如果它们是在创建活动或创建活动的其他子活动中创建的)。它们导致该活动未完成,即使返回了 Execute 方法。最终 Persist 将执行(在活动完成之后或进入空闲状态之前)。
于 2015-08-12T07:48:30.193 回答
0

如果我正确理解您的问题,那么您有以下要求。

  1. 工作流的持久性和恢复。
  2. 用户可以暂停和恢复。
  3. 如果出现任何异常,工作流会持续并从下一个活动恢复。

您可以使用以下步骤进行处理。

  1. 您可以使用 WF + WCF 服务来执行和托管您的工作流。
  2. 使用 Sql server 等数据库添加持久性和跟踪,如果您使用的是 oracle,则可以使用 Devart。
  3. 将 ControlEnpont 配置为暂停和恢复。
  4. 明智地使用 try/Catch 和持久性活动来处理异常。

如果有任何问题和需要定制的讨论相同。:) 因为我已经开发了与您类似的工作流程。

于 2015-06-14T11:18:13.490 回答