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


Пользовательский композит с использованием нативной активности

В примере CustomCompositeNativeActivity показано, как написать NativeActivity объект, который планирует другие Activity объекты для управления потоком выполнения рабочего процесса. В этом образце используются два общих потока управления, Sequence и While, для демонстрации того, как это сделать.

Подробные сведения об образце

Прежде всего об объекте MySequence следует отметить, что он является производным от NativeActivity. NativeActivity - объект Activity, который предоставляет доступ ко всем возможностям среды выполнения рабочего процесса с помощью объекта NativeActivityContext, передаваемого методу Execute.

Элемент MySequence предоставляет доступ к общедоступной коллекции объектов Activity, которая заполняется разработчиком рабочего процесса. Перед выполнением рабочего процесса среда выполнения рабочего процесса вызывает метод CacheMetadata для каждого действия в рабочем процессе. В ходе этого процесса среда выполнения определяет связи типа «родитель-потомок» в целях управления областью определения данных и временем существования. Реализация метода по умолчанию использует класс экземпляра CacheMetadata для активности MySequence, чтобы добавить любое общедоступное свойство типа Activity или IEnumerable<Activity> как дочерние элементы активности MySequence.

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

Помимо общедоступных переменных, которые изменяются дочерними элементами MySequence, MySequence должно также отслеживать, где оно находится в процессе выполнения своих дочерних элементов. Для этого в нем используется закрытая переменная currentIndex. Эта переменная регистрируется в составе MySequence среды путем добавления вызова метода AddImplementationVariable в метод CacheMetadata действия MySequence. Объекты, Activity добавленные в коллекцию MySequenceActivities , не могут получить доступ к переменным, добавленным таким образом.

При выполнении MySequence среда выполнения вызывает его метод Execute, передавая в него NativeActivityContext. Это NativeActivityContext — прокси-сервер действия, возвращающиеся в среду выполнения для разыменования аргументов и переменных, и планирования других Activity объектов или ActivityDelegates. MySequence использует метод InternalExecute для инкапсуляции логики планирования работы первого дочернего элемента и всех последующих дочерних элементов в единственном методе. Это начинается с разыменования currentIndex. Если это значение равно количеству в коллекции Activities, то последовательность завершается, и активность возвращается без назначения работы, а среда выполнения переводит её в состояние Closed. Если значение currentIndex меньше числа операций, следующий дочерний элемент получается из коллекции Activities, и затем MySequence вызывает ScheduleActivity, передавая дочерний элемент, который должен быть запланирован, и CompletionCallback указывая на метод InternalExecute. Наконец, значение currentIndex увеличивается и управление снова передается исполняемой среде. Пока экземпляр MySequence имеет запланированный дочерний объект Activity, среда выполнения считает, что он находится в состоянии выполнения.

После завершения дочерней активности выполняется CompletionCallback. Цикл продолжается снова с начала. Как и Execute, CompletionCallback принимает NativeActivityContext, предоставляя возможность использовать среду выполнения.

MyWhile отличается от MySequence тем, что он планирует один и тот же объект Activity многократно, и тем, что он использует переменную логического типа Activity<TResult><bool> с именем Condition, чтобы определить, должно ли происходить это планирование. Как и MySequence, MyWhile использует метод InternalExecute для централизации его логики планирования. Он планирует ConditionActivity<булево значение> с CompletionCallback<TResult><булевым значением>, названным OnEvaluationCompleted. После завершения выполнения Condition его результат становится доступным через это CompletionCallback в строго типизированном параметре с именем result. Если true, MyWhile вызывает ScheduleActivity, передавая объект BodyActivity и InternalExecute как CompletionCallback. После завершения выполнения Body, Condition снова планируется в InternalExecute, начиная цикл заново. Если Condition возвращает значение false, экземпляр MyWhile передает управление среде выполнения без планирования Body, а среда выполнения переводит его в состояние Closed.

Установка, сборка и выполнение примера

  1. Откройте пример решения Composite.sln в Visual Studio.

  2. Выполните сборку и запуск решения.