非泛型 ParallelForEachNon-generic ParallelForEach

.NET Framework 4.6.1.NET Framework 4.6.1 的工具箱中附带了一组控制流活动,其中包括可用来循环访问 ParallelForEach<T> 集合的 IEnumerable<T>ships in its toolbox a set of Control Flow activities, including ParallelForEach<T>, which allows iterating through IEnumerable<T> collections.

ParallelForEach<T> 要求其 Values 属性为 IEnumerable<T>类型。ParallelForEach<T> requires its Values property to be of type IEnumerable<T>. 这将阻止用户循环访问实现 IEnumerable<T> 接口(例如,ArrayList)的数据结构。This precludes users from iterating over data structures that implement IEnumerable<T> interface (for example, ArrayList). 非泛型版本的 ParallelForEach<T> 没有这一需求,不过与此对应的代价是,需要更复杂的运行时来确保集合中的值类型的兼容性。The non-generic version of ParallelForEach<T> overcomes this requirement, at the expense of more run-time complexity for ensuring the compatibility of the types of the values in the collection.

此示例演示如何实现非泛型的 ParallelForEach<T> 活动及其设计器。This sample shows how to implement a non-generic ParallelForEach<T> activity and its designer. 此活动可用于循环访问 ArrayListThis activity can be used to iterate through ArrayList.

ParallelForEach 活动ParallelForEach activity

C#/Visual Basic foreach 语句枚举集合中的元素,并对集合中的每个元素执行嵌入语句。The C#/Visual Basic foreach statement enumerates the elements of a collection, executing an embedded statement for each element of the collection. WFWF 等效活动为 ForEach<T>ParallelForEach<T>The WFWF equivalent activities are ForEach<T> and ParallelForEach<T>. ForEach<T> 活动包含一个值列表和一个主体。The ForEach<T> activity contains a list of values and a body. 在运行时,将循环访问此列表,并对列表中的每个值执行主体。At runtime, the list is iterated and the body is executed for each value in the list.

ParallelForEach<T> 具有一个 CompletionCondition,以便在 ParallelForEach<T> 的计算返回 CompletionCondition 的情况下,true 活动能够及早完成。ParallelForEach<T> has a CompletionCondition, so that the ParallelForEach<T> activity could complete early if the evaluation of the CompletionCondition returns true. 在每次迭代完成之后,将计算 CompletionConditionThe CompletionCondition is evaluated after each iteration is completed.

对于大多数情况,此活动的泛型版本应为首选解决方案,因为它涵盖了应使用此活动的大多数方案,并且提供编译时类型检查。For most cases, the generic version of the activity should be the preferred solution, because it covers most of the scenarios in which it is used and provides type checking at compile time. 非泛型版本可用于循环访问实现非泛型 IEnumerable 接口的类型。The non-generic version can be used for iterating through types that implement the non-generic IEnumerable interface.

类定义Class definition

下面的代码示例显示非泛型 ParallelForEach 活动的定义。The following code example shows the definition of a non-generic ParallelForEach activity is.

[ContentProperty("Body")]
public class ParallelForEach : NativeActivity
{
    [RequiredArgument]
    [DefaultValue(null)]
    InArgument<IEnumerable> Values { get; set; }

    [DefaultValue(null)]
    [DependsOn("Values")]
    public Activity<bool> CompletionCondition
    [DefaultValue(null)]
    [DependsOn("CompletionCondition")]
    ActivityAction<object> Body { get; set; }
}

Body (可选) Body (optional)
ActivityAction 类型的 Object,将对集合中的每个元素执行它。The ActivityAction of type Object, which is executed for each element in the collection. 通过单个元素的 Argument 属性将其传递到 Body。Each individual element is passed into the Body through its Argument property.

值(可选) Values (optional)
循环访问的元素集合。The collection of elements that are iterated over. 在运行时确保所有集合元素为兼容类型。Ensuring that all elements of the collection are of compatible types is done at run-time.

CompletionCondition (可选) CompletionCondition (optional)
在任何迭代完成之后,将计算 CompletionCondition 属性。The CompletionCondition property is evaluated after any iteration completes. 如果其计算结果为 true,则取消已安排的挂起的迭代。If it evaluates to true, then the scheduled pending iterations are canceled. 如果未设置此属性,则 Branches 集合中的所有活动都将执行,直至完成为止。If this property is not set, all activities in the Branches collection execute until completion.

使用 ParallelForEach 的示例Example of using ParallelForEach

下面的代码演示如何在应用程序中使用 ParallelForEach 活动。The following code demonstrates how to use the ParallelForEach activity in an application.

string[] names = { "bill", "steve", "ray" };

DelegateInArgument<object> iterationVariable = new DelegateInArgument<object>() { Name = "iterationVariable" };

Activity sampleUsage =
    new ParallelForEach
    {
       Values = new InArgument<IEnumerable>(c=> names),
       Body = new ActivityAction<object>
       {
           Argument = iterationVariable,
           Handler = new WriteLine
           {
               Text = new InArgument<string>(env => string.Format("Hello {0}",                                                               iterationVariable.Get(env)))
           }
       }
   };

ParallelForEach 设计器ParallelForEach designer

此示例的活动设计器的外观与为内置 ParallelForEach<T> 活动提供的设计器的外观相似。The activity designer for the sample is similar in appearance to the designer provided for the built-in ParallelForEach<T> activity. 设计器将显示在工具箱中的 "示例"、"非泛型" 活动类别。The designer appears in the toolbox in the Samples, Non-Generic Activities category. 设计器在 "工具箱" 中名为 " ParallelForEachWithBodyFactory ",因为活动在工具箱中公开了一个 IActivityTemplateFactory,该活动使用正确配置的 ActivityAction创建活动。The designer is named ParallelForEachWithBodyFactory in the toolbox, because the activity exposes an IActivityTemplateFactory in the toolbox that creates the activity with a properly configured ActivityAction.

public sealed class ParallelForEachWithBodyFactory : IActivityTemplateFactory
{
    public Activity Create(DependencyObject target)
    {
        return new Microsoft.Samples.Activities.Statements.ParallelForEach()
        {
            Body = new ActivityAction<object>()
            {
                Argument = new DelegateInArgument<object>()
                {
                    Name = "item"
                }
            }
        };
    }
}

运行示例To run the sample

  1. 将您选择的项目设置为解决方案的启动项目。Set the project of your choice as the startup project of the solution.

    1. CodeTestClient演示如何使用代码使用活动。CodeTestClient shows how to use the activity using code.

    2. DesignerTestClient演示如何在设计器中使用活动。DesignerTestClient shows how to use the activity within the designer.

  2. 生成并运行该项目。Build and run the project.

重要

您的计算机上可能已安装这些示例。The samples may already be installed on your machine. 在继续操作之前,请先检查以下(默认)目录:Check for the following (default) directory before continuing.

<InstallDrive>:\WF_WCF_Samples

如果此目录不存在,请参阅.NET Framework 4 的 Windows Communication Foundation (wcf)和 Windows Workflow Foundation (WF)示例以下载所有 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\Scenario\ActivityLibrary\NonGenericParallelForEach