活动树检查

活动树检查由工作流应用程序作者用于检查由应用程序承载的工作流。 使用 WorkflowInspectionServices,可以在工作流中搜索特定子活动、单个活动并可以枚举其属性,还可以在特定时间缓存活动的运行时元数据。 此主题概述 WorkflowInspectionServices 以及如何将其用于检查活动树。

使用 WorkflowInspectionServices

GetActivities 方法用于枚举指定活动树中的所有活动。 GetActivities 返回一个可枚举对象,该对象涉及树中包括子活动在内的所有活动、委托处理程序、变量默认值和参数表达式。 在下面的示例中,使用 SequenceWhileForEach<T>WriteLine 和表达式创建一个工作流定义。 在创建工作流定义后,将调用此定义,然后再调用 InspectActivity 方法。

Variable<List<string>> items = new Variable<List<string>>
{
    Default = new VisualBasicValue<List<string>>("New List(Of String)()")
};

DelegateInArgument<string> item = new DelegateInArgument<string>();

Activity wf = new Sequence
{
    Variables = { items },
    Activities =
    {
        new While((env) => items.Get(env).Count < 5)
        {
            Body = new AddToCollection<string>
            {
                Collection = new InArgument<ICollection<string>>(items),
                Item = new InArgument<string>((env) => "List Item " + (items.Get(env).Count + 1))
            }
        },
        new ForEach<string>
        {
            Values = new InArgument<IEnumerable<string>>(items),
            Body = new ActivityAction<string>
            {
                Argument = item,
                Handler = new WriteLine
                {
                    Text = item
                }
            }
        },
        new Sequence
        {
            Activities =
            {
                new WriteLine
                {
                    Text = "Items added to collection."
                }
            }
        }
    }
};

WorkflowInvoker.Invoke(wf);

InspectActivity(wf, 0);

为了枚举活动,在根活动上调用了 GetActivities,并在返回的每个活动上重新递归调用。 在下面的示例中,将活动树中每个活动和表达式的 DisplayName 写入控制台。

static void InspectActivity(Activity root, int indent)
{
    // Inspect the activity tree using WorkflowInspectionServices.
    IEnumerator<Activity> activities =
        WorkflowInspectionServices.GetActivities(root).GetEnumerator();

    Console.WriteLine("{0}{1}", new string(' ', indent), root.DisplayName);

    while (activities.MoveNext())
    {
        InspectActivity(activities.Current, indent + 2);
    }
}

此示例代码提供以下输出。

List Item 1
List Item 2List Item 3List Item 4List Item 5Items 添加到集合。SequenceLiteral<List<String>>
While
AddToCollection<String>
VariableValue<ICollection<String>>
LambdaValue<String>
LocationReferenceValue<List<String>>
LambdaValue<Boolean>
LocationReferenceValue<List<String>>
ForEach<String>
VariableValue<IEnumerable<String>>
WriteLine
DelegateArgumentValue<String>
序列
WriteLine
Literal<String> 要检索特定活动而非枚举所有活动,请使用 Resolve。 如果以前没有调用过 Resolve,则 GetActivitiesWorkflowInspectionServices.CacheMetadata 均会执行元数据缓存。 如果已调用过 CacheMetadata,则 GetActivities 基于现有元数据。 因此,如果自上次调用 CacheMetadata 以来对树进行了更改,则 GetActivities 可能会产生意外的结果。 如果在调用 GetActivities 后对工作流进行了更改,则可以通过调用 ActivityValidationServices Validate 方法重新缓存元数据。 缓存元数据在下一节中讨论。

缓存元数据

缓存某个活动的元数据将生成并验证活动的自变量、变量、子活动和活动委托的描述。 默认情况下,元数据在准备执行某个活动时由运行时缓存。 例如,如果工作流主机作者希望在此之前缓存某个活动或活动树的元数据,以便提前使用所有开销,则可使用 CacheMetadata 在需要时缓存元数据。