3 深入分析Activity执行的流程
一个Activity实例到底是如何执行的?一切得从WorkItem类开始。
WorkItem是一个抽象基类,提供了几个抽象方法,其中最重要的就是Execute()方法:
{
//……
private ActivityInstance activityInstance;
public abstract bool Execute(ActivityExecutor executor,
BookmarkManager bookmarkManager);
}
上述声明中还有两个很重要的类ActivityInstance和ActivityExecutor。
ActivityInstance代表着正在运行的一个Activity实例,它包容一堆的internal方法可以完成Activity的执行(Execute)取消(Cancel)和放弃(Abort)的功能。 ActivityExecutor则负责调用ActivityInstance中的这些方法。
WorkItem有一堆的子类,这些子类又派生出“孙”类。比如,其中的一个分支如下:

不管有几个子孙,后代一般都重写了WorkItem所定义的Execute()抽象方法。
我们以ExecuteRootWorkItem类为例,顾名思义,这应该是与工作流中最顶层的Activity相对应的WorkItem。它的Execute()方法如下所示:
{
return base.ExecuteBody(executor, bookmarkManager, this.resultLocation);
}
它将调用基类ExecuteActivityWorkItem的ExecuteBody()方法,此方法的关键代码如下:
{
//……
base.ActivityInstance.Execute(executor, bookmarkManager);
//……
}
可以看到,它直接跳去执行最顶层基类WorkItem所定义的ActivityInstance对象的Execute()方法。此方法的代码如下:
{
//……
this.Activity.InternalExecute(this, executor, bookmarkManager);
}
注意ActivityInstance实际上封装了一个Activity对象:
{
public Activity Activity { get; internal set; }
//……
}
所以,ActivityInstance对象的Execute()方法实际上执行的是Activity对象的InternalExecute()方法。再追踪下去:
{
//……
executor.ScheduleActivity(this.runtimeImplementation, instance, null, null, null);
}
注意:上述代码是Acitivity对InternalExecute()默认的实现方式,它的子类(比如CodeActivity)通常会重写它。
可以看到,在ActivityInstance对象的Execute()方法中,执行流程转给了从前面一路传送过来的ActivityExecutor对象,由此对象的ScheduleActivity方法负责将Activity插入到工作项队列中。
ActivityExecutor.ScheduleActivity方法又进行了一个“倒手”,调用自己的ScheduleBody()方法:
{
//……
this.ScheduleBody(scheduledInstance, requiresSymbolResolution, argumentValueOverrides, resultLocation);
}
在ScheduleBody()方法中,“佛祖”终于现出真身,我们看到了Scheduler的身影:
{
if (resultLocation == null)
{
//……
this.scheduler.PushWork(new ExecuteExpressionWorkItem(activityInstance, requiresSymbolResolution, argumentValueOverrides, resultLocation));
//……
}
在上述代码中,Scheduler对象将activityInstance转换为了一个ExecuteExpressionWorkItem,然后将其插入到工作项队列中等待执行。
现在我们看到,默认情况下,对ExecuteRootWorkItem的执行将导致一个新的ExecuteExpressionWorkItem工作项被插入到工作项队列中。