Пользовательское составное действие, использующее собственное действиеCustom Composite using Native Activity

В этом образце показано, как разработать действие NativeActivity, которое планирует другие объекты Activity для управления потоком выполнения рабочего процесса.This sample demonstrates how to write a NativeActivity that schedules other Activity objects to control the flow of a workflow’s execution. В этом образце используются два общих потока управления, Sequence и While, для демонстрации того, как это сделать.This sample uses two common control flows, Sequence and While, to demonstrate how to do this.

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

Прежде всего об объекте MySequence следует отметить, что он является производным от NativeActivity.Starting with MySequence, the first thing to notice is that it derives from NativeActivity. NativeActivity - объект Activity, который предоставляет доступ ко всем возможностям среды выполнения рабочего процесса с помощью объекта NativeActivityContext, передаваемого методу Execute.NativeActivity is the Activity object that exposes the full breadth of the workflow runtime through the NativeActivityContext passed to the Execute method.

Действие MySequence предоставляет доступ к общедоступной коллекции объектов Activity, которая заполняется разработчиком рабочего процесса.MySequence exposes a public collection of Activity objects that gets populated by the workflow author. Перед выполнением рабочего процесса среда выполнения рабочего процесса вызывает метод CacheMetadata для каждого действия в рабочем процессе.Before the workflow is executed, the workflow runtime calls the CacheMetadata method on each activity in a workflow. В ходе этого процесса среда выполнения определяет связи типа «родитель-потомок» в целях управления областью определения данных и временем существования.During this process, the runtime establishes parent-child relationships for data scoping and lifetime management. CacheMetadata Реализация метода по умолчанию Activity Activity TypeDescriptor использует класс экземпляра для MySequence действия, чтобы добавить любое открытое свойство типа или IEnumerable <> в качестве дочерних элементов MySequence действие.The default implementation of the CacheMetadata method uses the TypeDescriptor instance class for the MySequence activity to add any public property of type Activity or IEnumerable<Activity> as children of the MySequence activity.

Каждый раз, когда действие предоставляет доступ к общедоступной коллекции дочерних действий, возникает вероятность того, что эти дочерние действия будут приобретать одинаковое состояние.Whenever an activity exposes a public collection of child activities, it is likely those child activities share state. Рекомендуется, чтобы родительское действие, в данном случае MySequence, также предоставляло доступ к коллекции переменных, с помощью которых дочерние действия могли бы это осуществить.It is a best practice for the parent activity, in this case MySequence, to also expose a collection of variables through which the child activities can accomplish this. Как и в случае с CacheMetadata дочерними действиями, Variable метод IEnumerableдобавляет открытые свойства типа или < Variable> MySequence в виде переменных, связанных с действием.Like child activities, the CacheMetadata method adds public properties of type Variable or IEnumerable<Variable> as variables associated with the MySequence activity.

Помимо общедоступных переменных, которыми управляют действия, дочерние по отношению к MySequence, действие MySequence должно также следить, где оно находится с точки зрения выполнения его дочерних действий.Besides the public variables, which are manipulated by the children of MySequence, MySequence must also keep track of where it is in the execution of its children. Для этого в нем используется закрытая переменная currentIndex.It uses a private variable, currentIndex, to accomplish this. Эта переменная регистрируется как часть среды MySequence путем добавления вызова метода AddImplementationVariable в метод MySequence действия CacheMetadata.This variable is registered as part of the MySequence environment by adding a call to the AddImplementationVariable method within the MySequence activity’s CacheMetadata method. Объекты Activity, добавленные в коллекцию MySequence Activities, не могут получить доступ к переменным, добавленным таким образом.The Activity objects added to the MySequence Activities collection cannot access variables added this way.

При выполнении средой выполнения действия MySequence она вызывает его метод Execute, передавая ему контекст NativeActivityContext.When MySequence is executed by the runtime, the runtime calls its Execute method, passing in an NativeActivityContext. NativeActivityContext выполняет для действия роль посредника к среде выполнения для разыменования аргументов и переменных, а также планирования работы других объектов Activity или ActivityDelegates.The NativeActivityContext is the activity’s proxy back into the runtime for dereferencing arguments and variables as well as scheduling other Activity objects, or ActivityDelegates. MySequence использует метод InternalExecute для инкапсуляции логики планирования работы первого дочернего элемента и всех последующих дочерних элементов в единственном методе.MySequence uses an InternalExecute method to encapsulate the logic of scheduling the first child and all subsequent children in a single method. Он начинает свое функционирование с разыменования currentIndex.It starts by dereferencing the currentIndex. Если это значение равно количеству в коллекции Activities, то последовательность завершается, действие выполняет возврат без планирования какой-либо работы и среда выполнения переводит его в состояние Closed.If it is equal to the count in the Activities collection, then the sequence is finished, the activity returns without scheduling any work and the runtime moves it into the Closed state. Если значение currentIndex меньше числа действий, то следующий дочерний объект получается Activities из коллекции и MySequence вызывает ScheduleActivity, передавая дочерний элемент для планирования и объект CompletionCallback , указывающий на InternalExecute Method.If the currentIndex is less than the count of activities, the next child is obtained from the Activities collection and MySequence calls ScheduleActivity, passing in the child to be scheduled and a CompletionCallback that points at the InternalExecute method. Наконец, значение currentIndex увеличивается и управление снова передается среде выполнения.Finally, the currentIndex is incremented and control is yielded back to the runtime. Пока экземпляр действия MySequence имеет запланированный дочерний объект Activity, среда выполнения считает, что оно находится в состоянии выполнения.As long as an instance of MySequence has a child Activity object scheduled, the runtime considers it to be in the Executing state.

После завершения дочернего действия выполняется CompletionCallback.When the child activity completes, the CompletionCallback is executed. Выполнение цикла продолжается с его верхней части.The loop continues from the top. Как и метод Execute, обратный вызов CompletionCallback принимает контекст NativeActivityContext, предоставляя средству реализации доступ к среде выполнения.Like Execute, a CompletionCallback takes an NativeActivityContext, giving the implementer access to the runtime.

MyWhileотличается от MySequence в том, что он регулярно Activity планирует один объект, а также использует Activity<TResult>< bool> с именем Condition , чтобы определить, должно ли выполняться планирование.MyWhile differs from MySequence in that it schedules a single Activity object repeatedly, and in that it uses a Activity<TResult><bool> named Condition to determine whether this scheduling should occur. Как и действие MySequence, действие MyWhile использует метод InternalExecute для централизации своей логики планирования.Like MySequence, MyWhile uses an InternalExecute method to centralize its scheduling logic. Он Conditionпланирует Activity< CompletionCallback<TResult>bool> с > bool<с именем. OnEvaluationCompletedIt schedules the ConditionActivity<bool> with a CompletionCallback<TResult><bool> named OnEvaluationCompleted. После завершения выполнения проверки Condition ее результат становится доступным через этот обратный вызов CompletionCallback в строго типизированном параметре с именем result.When the execution of Condition is completed, its result becomes available through this CompletionCallback in a strongly-typed parameter named result. Если значение равно true, действие MyWhile вызывает метод ScheduleActivity, передавая объект Body типа Activity и метод InternalExecute в качестве обратного вызова CompletionCallback.If true, MyWhile calls ScheduleActivity, passing in the BodyActivity object and InternalExecute as the CompletionCallback. После завершения выполнения Body проверка Condition планируется еще раз в действии InternalExecute, что приводит к очередному запуску цикла.When the execution of Body completes, Condition gets scheduled again in InternalExecute, starting the loop over again. Если проверка Condition возвращает значение false, экземпляр действия MyWhile передает управление среде выполнения без планирования Body, а среда выполнения переводит действие в состояние Closed.When the Condition returns false, an instance of MyWhile gives control back to the runtime without scheduling the Body and the runtime moves it to the Closed state.

Настройка, сборка и выполнение образцаTo set up, build, and run the sample

  1. Откройте пример решения Composite. sln в Visual Studio 2010.Open the Composite.sln sample solution in Visual Studio 2010.

  2. Постройте и запустите это решение.Build and run the solution.

Важно!

Образцы уже могут быть установлены на компьютере.The samples may already be installed on your machine. Перед продолжением проверьте следующий каталог (по умолчанию).Check for the following (default) directory before continuing.

<InstallDrive>:\WF_WCF_Samples

Если этот каталог не существует, перейдите к примерам Windows Communication Foundation (WCF) и Windows Workflow Foundation (WF) для .NET Framework 4 , чтобы скачать все Windows Communication Foundation (WCF) WFWF и примеры.If this directory does not exist, go to Windows Communication Foundation (WCF) and Windows Workflow Foundation (WF) Samples for .NET Framework 4 to download all Windows Communication Foundation (WCF) and WFWF samples. Этот образец расположен в следующем каталоге.This sample is located in the following directory.

<InstallDrive>:\WF_WCF_Samples\WF\Basic\CustomActivities\Code-Bodied\CustomCompositeNativeActivity