State Machine WF:工作流程终止的问题

时间:2010-04-03 17:26:30

标签: workflow workflow-foundation state-machine-workflow

我们有一个状态机工作流程,用于维护用户提交的应用程序的状态。我遇到的一个问题与工作流程终止有关。在其中一个州,我有一个错误。当应用程序到达该状态时,它抛出异常,结果,调用了工作流的终止事件,并从持久性数据库中删除了特定的工作流实例。所以我不能再加载该工作流实例了。我希望,如果其中一个状态出现错误,将抛出异常(以便我们知道问题是什么),但整个工作流实例不应该消失。故障处理程序活动是否可以确保工作流不会终止。另外,有没有办法,当调用terminate事件时,实例不会从持久性存储中删除。

感谢您提供任何帮助/建议。

3 个答案:

答案 0 :(得分:2)

当在工作流中抛出异常时,异常将通过活动祖先有效地“冒泡”,直到它为止:

  1. 由故障处理程序活动处理
  2. 达到根活动(即:工作流本身),此时工作流将终止。
  3. 最好在正确的位置为所有可能的例外创建故障处理程序。使用故障处理程序活动,您可以恢复工作流实例,并有效地将状态机设置回可用状态而不是终止它。

    一旦工作流程终止,它就无法使用,因此在终止发生后将其保留在持久性存储中没有任何好处,这就是它被删除的原因。所以你可以看到,关键是要阻止它意外终止。

    最后一个提示。当工作流终止时,导致终止的异常将作为WorkflowTerminatedEventArgs对象的Exception属性发送到事件侦听器。我绝对建议使用某种日志记录机制来捕获它并将其输出到某个地方,这样如果你将来遇到因某些原因未被捕获的错误,那么跟踪它们会更加容易。

答案 1 :(得分:0)

我创建了一个自定义SQL工作流持久性服务,可防止工作流实际终止 - 从而使工作流处于导致错误的转换之前的先前状态:

public class CustomSqlWorkflowPersistenceService : SqlWorkflowPersistenceService
    {
        public CustomSqlWorkflowPersistenceService (string connectionString) : base(connectionString)
        {
        }

        public CustomSqlWorkflowPersistenceService (NameValueCollection parameters) : base(parameters)
        {
        }

        public CustomSqlWorkflowPersistenceService (string connectionString, bool unloadOnIdle, TimeSpan instanceOwnershipDuration, TimeSpan loadingInterval) : base(connectionString, unloadOnIdle, instanceOwnershipDuration, loadingInterval)
        {
        }

        protected override void SaveWorkflowInstanceState(Activity rootActivity, bool unlock)
        {
            WorkflowStatus workflowStatus = GetWorkflowStatus(rootActivity);
            if (workflowStatus == WorkflowStatus.Terminated)
            {
                string workflowError = GetSuspendOrTerminateInfo(rootActivity);
                if (!string.IsNullOrEmpty(workflowError))
                {
                    string error = string.Format("Workflow terminated, forcing an abort! {0}", workflowError);
                    throw new Exception(error);
                }
            }
            base.SaveWorkflowInstanceState(rootActivity, unlock);
        }
    }

如果你想迫使一个WF终止,这显然会很痛苦,但我相信你可以解决这个问题。

答案 2 :(得分:0)

我正在使用SqlWorkflowPersistence,作为对此的修复我执行了以下操作:

在'WorkflowPersistence'数据库中,我们有SP'InsertInstanceState'来删除实例。我评论了删除实例的代码。

看起来它的工作但我不确定这是否正确。

SP的一部分如下所示,我改变了。

IF
@status=1 OR @status=3          
    BEGIN      

/* DELETE FROM [dbo].[InstanceState] WHERE uidInstanceID=@uidInstanceID AND ((ownerID = @ownerID AND ownedUntil>=@now) 
 OR (ownerID IS NULL AND @ownerID IS NULL ))          
*/
    END