工作流持久性和书签作为工作流故障转移

时间:2015-06-10 07:52:00

标签: c# workflow-foundation-4 workflow-foundation workflow-activity sqlworkflowpersistencese

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

我希望在没有工作流处于空闲状态的情况下使它们(自定义活动)保持不变。它应该是一种故障转移系统,因此在执行工作流时出现问题时,它可以是:

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

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

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

您能告诉我,它的工作流程书签是什么方式?

我看到一些禁止书签的亮点,但我不能坚持下去并稍后恢复。你能不能给我一些提示,告诉我如何为以后的简历保留一个非阻塞书签?

修改

在wf3中有一个属性PersistOnClose,这足以满足我的要求。 在wf4中,它被Persist活动取代,这也很有用,但我不希望在我已经很复杂的工作流程中有额外的活动。

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

2 个答案:

答案 0 :(得分: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将执行(在活动完成后或进入空闲状态之前)。

答案 1 :(得分:0)

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

  1. 工作流程的持久性和恢复。
  2. 用户可以暂停和恢复。
  3. 如有任何异常,工作流程会持续存在并从下一个活动中恢复。
  4. 您可以使用以下步骤进行操作。

    1. 您可以使用WF + WCF服务来执行和托管您的工作流程。
    2. 使用像Sql server这样的数据库添加持久性和跟踪,如果您使用的是oracle,则可以使用Devart。
    3. 配置ControlEnpont以暂停和恢复。
    4. 明智地使用try / Catch和持久性活动来处理异常。
    5. 如果出现任何问题和定制需要讨论相同。:)因为我已经开发了类似于你的工作流程。