- 理解AEC(ActivityExecutionContext)
当Workflow runtime执行一个Activity时,他会为这个Activity新建一个ActivityExecutionContext,它包含了执行Activity信息。更重要的一点是AEC是根据Activity临时变化的并且这个Activity是深copy,所以就很难得到执行这个Activity之前得AEC和Activity实例。当一个Activity执行多次的时候,他必须被copy多次,同时AEC也创建一个新的,代码:
ActivityExecutionContextchildContext=currentContext.ExecutionContextManager.CreateExecutionContext(childActivity);
它将会根据父AEC去为ChildActivity创建一个新的AEC,以维护自己。假设我们有一个自定义的Activity叫WorkflowRoot,我们去copy它的子Activity,会有以下结果:
RootContext
| WorkflowRoot (1)
| childActivity (1)
| grandChildActivity (1)
- childContext
childActivity (2)
grandChildActivity (2)
有2个问题:
- childActivity(1) or childActivity(2) 相互有影响么?
一旦Clone了这个实例,这2个实例就 没有联系了。
- childActivity(2)的父Activity是谁?
WorkflowRoot (1),所以新clone的Activity的父activity任然执行原Activity
- 分析SequenceActivityandConditionedActivityGroup
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方法。②告诉我们要手工执行这个Activityvoid 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- 自定义一个Rollback的Activity
自定义了一个NavigatorActivity,他的功能就是可以rollback或forward到一个Activity,当我从一个Activity到另一个activity,
- 创建了一个NavigateRequest类,用以存储源activity和目标activity,
- 然后把他用外部服务传入workflowRuntime的WorkflowQueueingService里,
- 然后在Excute()检查NavigateRequest是否存在,如果存在,将会停掉现在执行的Activity,将调度到目标Activity里。可以通过ConditionedActivityGroup去了解Activity执行的过程
整个的架构
定义NavigateRequest类:
注册rollbackactivity
根据检查是否要rollback,然后去schedule目标activity
参考文档:<http://blogs.msdn.com/b/advancedworkflow/archive/2006/03/21/557121.aspx>