分析SequenceActivity和ConditionedActivityGroup来自定义一个可以回滚的Activity

 

  1. 理解AECActivityExecutionContext
  2. Workflow runtime执行一个Activity时,他会为这个Activity新建一个ActivityExecutionContext,它包含了执行Activity信息。更重要的一点是AEC是根据Activity临时变化的并且这个Activity是深copy,所以就很难得到执行这个Activity之前得AECActivity实例。当一个Activity执行多次的时候,他必须被copy多次,同时AEC也创建一个新的,代码:

    ActivityExecutionContextchildContext=currentContext.ExecutionContextManager.CreateExecutionContext(childActivity);

    它将会根据父AEC去为ChildActivity创建一个新的AEC,以维护自己。假设我们有一个自定义的ActivityWorkflowRoot,我们去copy它的子Activity,会有以下结果:

    RootContext

    |      WorkflowRoot (1)

    |         childActivity (1)

    |            grandChildActivity (1)

    - childContext

             childActivity (2)

                grandChildActivity (2)

    2个问题

  3. childActivity(1) or childActivity(2) 相互有影响么?
  4. 一旦Clone了这个实例,这2个实例就 没有联系了。

  5. childActivity(2)的父Activity是谁?
  6. WorkflowRoot (1),所以新cloneActivity的父activity任然执行原Activity

  7. 分析SequenceActivityandConditionedActivityGroup
  8. SequenceActivity将一个一个执行它的子activity,执行完最后一个Activity后这个SequenceActivity将会关闭。

     

    protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
    {
       
    if (executionContext == null)
        {
           
    throw new ArgumentNullException("executionContext");
        }
       
    if (base.EnabledActivities.Count == 0)
        {
           
    this.OnSequenceComplete(executionContext);
           
    return ActivityExecutionStatus.Closed;
        }
       
    base.EnabledActivities[0].RegisterForStatusChange(Activity.ClosedEvent, this); //

        executionContext.ExecuteActivity(base.EnabledActivities[0]); //
       
    base.SetValue(ActiveChildQualifiedNameProperty, base.EnabledActivities[0].QualifiedName);
       
    return ActivityExecutionStatus.Executing;
    }
    ①注册了一个事件,当第一个Activity执行完毕后,将会触发OnEvent方法。②告诉我们要手工执行这个Activity

    void IActivityEventListener<ActivityExecutionStatusChangedEventArgs>.OnEvent(object sender, ActivityExecutionStatusChangedEventArgs e)
    {
       
    if (sender == null)
        {
           
    throw new ArgumentNullException("sender");
        }
       
    if (e == null)
        {
           
    throw new ArgumentNullException("e");
        }
       
    ActivityExecutionContext executionContext = sender as ActivityExecutionContext;
       
    if (executionContext == null)
        {
           
    throw new ArgumentException(SR.Error_SenderMustBeActivityExecutionContext, "sender");
        }
        e.
    Activity.UnregisterForStatusChange(Activity.ClosedEvent, this);
       
    SequenceActivity activity = executionContext.Activity as SequenceActivity;
       
    if (activity == null)
        {
           
    throw new ArgumentException("sender");
        }
       
    if ((activity.ExecutionStatus == ActivityExecutionStatus.Canceling) || ((activity.ExecutionStatus == ActivityExecutionStatus.Faulting) && ((bool) base.GetValue(SequenceFaultingProperty))))
        {
           
    if (activity.ExecutionStatus == ActivityExecutionStatus.Faulting)
            {
               
    base.RemoveProperty(SequenceFaultingProperty);
            }
           
    base.RemoveProperty(ActiveChildQualifiedNameProperty);
            executionContext.
    CloseActivity();
        }
       
    else if ((activity.ExecutionStatus == ActivityExecutionStatus.Executing) && !this.TryScheduleNextChild(executionContext))
        {
           
    this.OnSequenceComplete(executionContext);
            executionContext.
    CloseActivity();
        }
    }
    this.TryScheduleNextChild(executionContext)将执行下一个Activity

    然而ConditionedActivityGroup就较为复杂。它的子节点可能被执行多次,所以当子节点的状态为pending/executing/idle时,它将维护一个状态集合,当他要执行或重新执行这个Activity时,执行以下方法:

    private void ExecuteChild(ConditionedActivityGroup cag, Activity childActivity, ActivityExecutionContext context)
    {
       
    ActivityExecutionContext context2 = GetChildExecutionContext(context, childActivity, true);
        cag.
    CAGState.ChildrenStats[childActivity.QualifiedName].State = CAGChildState.Excuting;
        context2.
    Activity.RegisterForStatusChange(Activity.ClosedEvent, this);
        context2.
    ExecuteActivity(context2.Activity);
    }
    我们可以通过分析系统中的Activity去学习自己定义Activity

  9. 自定义一个RollbackActivity
  10. 自定义了一个NavigatorActivity,他的功能就是可以rollbackforward到一个Activity,当我从一个Activity到另一个activity

  11. 创建了一个NavigateRequest类,用以存储源activity和目标activity
  12. 然后把他用外部服务传入workflowRuntime的WorkflowQueueingService里,
  13. 然后在Excute()检查NavigateRequest是否存在,如果存在,将会停掉现在执行的Activity,将调度到目标Activity里。可以通过ConditionedActivityGroup去了解Activity执行的过程
  14. 整个的架构

    定义NavigateRequest类:

    注册rollbackactivity

    根据检查是否要rollback,然后去schedule目标activity

     

     参考文档:<http://blogs.msdn.com/b/advancedworkflow/archive/2006/03/21/557121.aspx>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值