Поделиться через


Анализ дерева действий

Проверка дерева действий используется авторами приложений рабочих процессов для проверки рабочих процессов, размещенных приложением. Используя службы WorkflowInspectionServices, в рабочих процессах можно искать определенные дочерние действия, отдельно взятые действия и их свойства могут быть перечислены, а метаданные действий времени выполнения могут быть кэшированы в определенное время. В этом разделе представлены общие сведения о службах WorkflowInspectionServices и их использовании для проверки дерева действий.

Использование WorkflowInspectionServices

Метод GetActivities используется для перечисления всех действий в указанном дереве действий. GetActivities возвращает перечислимый объект, который касается всех действий в дереве, включая дочерние действия, обработчики делегатов, значения переменных по умолчанию и выражения аргументов. В следующем примере создается определение рабочего процесса при помощи Sequence, While, ForEach<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);
    }
}

Результатом этого образца кода является следующее.

Элемент списка 1
Элемент 2списка 3элемента списка 4элемента списка 5, добавленных в коллекцию.Строка списка<литеральных строк<последовательности>>
While
Строка AddToCollection<>
Строка ICollection<VariableValue<>>
ЛямбдаЗначная<строка>
Строка списка<LocationReferenceValue<>>
ЛямбдаValue<Boolean>
Строка списка<LocationReferenceValue<>>
Строка forEach<>
Строка VariableValue<IEnumerable<>>
WriteLine
Строка делегатаArgumentValue<>
Последовательность
WriteLine
Используется литеральная<строка> для получения определенного действия вместо Resolve перечисления всех действий. Как Resolve, так GetActivities выполняют кэширование метаданных, если метод WorkflowInspectionServices.CacheMetadata не был вызван ранее. Если метод CacheMetadata уже был вызван, то GetActivities основывается на существующих метаданных. Таким образом, если с момента последнего вызова метода CacheMetadata в дерево были внесены изменения, GetActivities может возвратить неожиданные результаты. Если изменения были внесены в рабочий процесс после вызова GetActivities, метаданные можно повторно кэшировать, вызвав ActivityValidationServices Validate метод. Кэширование метаданных рассматривается в следующем разделе.

Кэширование метаданных

При кэшировании метаданных для действия создается и проверяется описание аргументов, переменных, дочерних действий и делегатов действия. По умолчанию метаданные кэшируются средой выполнения во время подготовки действия к выполнению. Если автору узла рабочего процесса необходимо кэшировать метаданные для действия или дерева действий раньше, например для выведения всех расходов на передний план, можно использовать метод CacheMetadata для выполнения кэширования метаданных в нужное время.