创建自定义流控制活动Creating custom flow control activities

.NET Framework 包含各种流控制活动,这些活动与抽象编程结构( Flowchart如)或标准编程语句( If如)的运行方式类似。The .NET Framework contains a variety of flow-control activities that function similarly to abstract programming structures (such as Flowchart) or to standard programming statements (such as If). 本主题讨论一个示例项目(非泛型 ForEach)的体系结构。This topic discusses the architecture of one of the sample projects, Non-Generic ForEach.

创建自定义类Creating the custom class

由于非泛型 ForEach 类将需要安排子活动,因此它需要从 NativeActivity 派生,这是因为派生自 CodeActivity 的活动不具有此功能。Since the Non-Generic ForEach class will need to schedule child activities, it will need to derive from NativeActivity, since activities that derive from CodeActivity do not have this functionality.

public sealed class ForEach : NativeActivity  
{
}

自定义类需要多个成员来存储活动所使用的数据,并提供用于执行该活动的子活动的功能。The custom class requires several members to store data being used by the activity, and to provide functionality to execute the activity’s child activities. 这些成员包括:These members include:

  • valueEnumerator:用于循环访问项Variable<T>集合的IEnumerator类型的非公共。valueEnumerator: The non-public Variable<T> of type IEnumerator used to iterate over the collection of items. 此成员的类型为 Variable<T>,由于它是在活动内部而非自变量或公共属性内部使用的,因此如果该对象具有活动外部的来源,则将使用此成员。This member is of type Variable<T> because it is used internally in the activity, rather than an argument or public property, which would be used if this object were to have an origin outside the activity.

  • OnChildComplete:每个子CompletionCallback元素完成执行时执行的公共属性。OnChildComplete: The public CompletionCallback property that executes when each child completes execution. 此成员将定义为 CLR 属性,因为其值将不会随活动实例的不同而不同。This member is defined as a CLR property, since its value will not change for different instances of the activity.

  • Values:用于子活动的迭代的输入集合。Values: The collection of inputs used for the iterations of the child activity. 此成员的类型为 InArgument<T>,因为该数据的来源位于活动外部,但集合的内容不应在活动执行期间发生更改。This member is of type InArgument<T>, since the origin of the data is outside the activity, but the contents of the collection is not expected to change during the execution of the activity. 如果该活动需要此功能以便在活动执行期间更改此集合的内容(例如,添加或移除活动),则此成员应已定义为 ActivityAction,之后,每当访问该成员时,系统都会对其进行计算,以使更改对该活动可用。If the activity needed the functionality to change the contents of this collection while the activity was executing (to add or remove activities, for instance), this member would have been defined as an ActivityAction, which then would have been evaluated every time it was accessed, so that changes would be available to the activity.

  • Body:此成员定义要为Values集合中的每个项执行的活动。Body: This member defines the activity to be executed for each item in the Values collection. 此成员定义为 ActivityAction,以便每当访问此成员时,系统都会对其进行计算。This member is defined as an ActivityAction so that it is evaluated every time it is accessed.

  • Execute:此方法使用InternalExecuteOnForEachCompleteGetStateAndExecute非公共成员来计划执行,并分配在正文成员中定义的子活动的完成处理程序。Execute: This method uses the InternalExecute, OnForEachComplete, and GetStateAndExecute non-public members to schedule the execution and assign the completion handler of the child activity defined in the Body member.

  • CacheMetadata:此成员为运行时提供执行活动所需的信息。CacheMetadata: This member provides the runtime with the information it needs to execute the activity. 默认情况下,一个活动的 CacheMetadata 方法会将该活动的所有公共成员告知运行时,但由于此活动对某些功能使用了私有成员,因此它需要告知运行时存在这些私有成员,以便运行时能注意到它们。By default, an activity’s CacheMetadata method will inform the runtime of all public members of the activity, but since this activity uses private members for some functionality, it needs to inform the runtime of their existence so that the runtime can be aware of them. 在此示例中,将重写 CacheMetadata 函数以便能访问私有 valueEnumerator 成员。In this case, the CacheMetadata function is overridden so that the private valueEnumerator member can be accessed. 此成员还为该活动的值创建了一个自变量,以便这些值能在执行期间传入该活动中。This member also creates an argument for the values for the activity so that they can be passed in to the activity during execution.