C# 作为工作流故障切换的工作流持久性和书签

C# 作为工作流故障切换的工作流持久性和书签,c#,workflow-foundation-4,workflow-foundation,workflow-activity,sqlworkflowpersistencese,C#,Workflow Foundation 4,Workflow Foundation,Workflow Activity,Sqlworkflowpersistencese,我有一组自定义活动,用于复杂的工作流 我想让它们(自定义活动)持久化,而不让工作流处于空闲状态。它应该是一种故障切换系统,因此在工作流执行过程中出现问题时,它可以是: 由用户暂停(在anytime中),然后从暂停的书签/点恢复(例如,用户注意到外部系统已关闭,他希望暂时暂停工作流) 如果出现未处理的异常,我们可以从最后一个书签/时间点重新开始执行 WorkflowApplication主机可以随时停止,我们可以从最后一个书签/时间点重新启动执行 我已经用工作流持久性工作了几天,但我不确定我是

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

我想让它们(自定义活动)持久化,而不让工作流处于空闲状态。它应该是一种故障切换系统,因此在工作流执行过程中出现问题时,它可以是:

  • 由用户暂停(在anytime中),然后从暂停的书签/点恢复(例如,用户注意到外部系统已关闭,他希望暂时暂停工作流)
  • 如果出现未处理的异常,我们可以从最后一个书签/时间点重新开始执行
  • WorkflowApplication主机可以随时停止,我们可以从最后一个书签/时间点重新启动执行
我已经用工作流持久性工作了几天,但我不确定我是否能用它实现我的目标。为什么?

  • 我可以在每个自定义活动中使用阻止书签,但是仅仅为了持久化而阻止工作流并重新启动它看起来不太可能
  • 我可以使用notblocking书签,但我无法在数据库中看到它们并从中恢复
你能给我提个建议吗?这里有书签吗

我从不阻止书签中看到了一些启示,但我无法将它们持久化并在以后继续。你能给我一些提示,如何为以后的简历保留一个非阻塞书签吗

编辑:

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


理想情况下,能够从
NativeActivityContext
执行
context.RequestPersist(callback)
,这将非常好,但是这个方法是内部的(并且它内部的所有内容在原始程序集之外都不可见)。

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

  • 工作流的持久性和恢复
  • 用户可以暂停和恢复
  • 在任何异常情况下,工作流将保持并从下一个活动继续
  • 您可以使用以下步骤来实现

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

  • 如有任何问题和定制要求,请与我所讨论的相同。:)因为我开发了与您类似的工作流程

    以下是我带来的:

    • 非阻塞书签不是一个选项。尽管非阻塞书签不会阻止创建活动的完成,但它也不会导致工作流实例变为空闲状态,这意味着它不会被持久化。一旦创建非阻塞书签的活动完成,非阻塞书签将被丢弃。只有在创建活动尚未完成时,才能恢复此书签
    • 使用
      PersistOnCloseAttribute
      不是一个选项,因为我使用的是WF4,而该属性仅为.NET 3.x WF
    • 无法使用阻止书签,因为它们阻止工作流的执行,这是不需要的
    解决方案是在每个定制活动中使用
    Persist
    活动(必须扩展可以安排子活动的
    NativeActivity
    ):

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

    protected override void CacheMetadata(NativeActivityMetadata metadata)
    {
         base.CacheMetadata(metadata);
         metadata.AddImplementationChild(this.childActivity);
    }
    
    最后一件事是从Execute方法调度子活动(无论在何处,持久性只会在调用活动完成后发生*)

    为了在未处理的异常之后保持工作流的持久性,必须将以下代码段添加到WorkflowApplication:

     application.OnUnhandledException = delegate(WorkflowApplicationUnhandledExceptionEventArgs e)
     {
          return UnhandledExceptionAction.Abort;
     };
    
    *从
    Execute
    方法返回并不一定意味着该活动已“完成”-即活动内有阻塞书签(见下文)

    此解决方案有几个缺点:

    • 解决方案只保留工作流的一种状态(最后一种状态)
    • 只有在活动完成时才能发生持久性。这意味着不能从活动的中间进行持久化/恢复
    • 它不适用于并行循环/序列-并行循环/序列中的活动在整个并行过程完成后被持久化。它可以正确地处理常规循环/序列
    • 阻止书签对此解决方案有很大影响(如果它们是在创建活动或创建活动的其他子活动中创建的)。它们导致活动未完成,即使返回Execute方法。最终将执行Persist(在活动完成后或进入空闲状态之前)
    protected override void Execute(NativeActivityContext context)
    {
        //...
        context.ScheduleActivity((Activity)this.childActivity);
    }
    
     application.OnUnhandledException = delegate(WorkflowApplicationUnhandledExceptionEventArgs e)
     {
          return UnhandledExceptionAction.Abort;
     };