非泛型 ParallelForEach

.NET Framework 4.6.1 在其工具箱中提供了一组控制流活动,包括 ParallelForEach<T>,可用于遍历 IEnumerable<T> 集合。

ParallelForEach<T> 要求其 Values 属性类型为 IEnumerable<T>。 这阻止用户循环访问实现IEnumerable<T>接口的数据结构(例如)。 ArrayList 非泛型版本 ParallelForEach<T> 克服了此要求,但代价是运行时复杂性更高,以确保集合中值的类型的兼容性。

NonGenericParallelForEach 示例演示如何实现非泛型ParallelForEach<T>活动及其设计器。 此活动可用于循环访问 ArrayList

ParallelForEach 活动

C#/Visual Basic foreach 语句枚举集合的元素,为集合的每个元素执行嵌入语句。 WF 等效活动是 ForEach<T>ParallelForEach<T>ForEach<T> 活动包含一个值列表和一个主体。 在运行时,会对列表进行迭代,并针对列表中的每个值执行正文。

ParallelForEach<T> 具有一个 CompletionCondition,以便在 ParallelForEach<T> 的计算返回 CompletionCondition 的情况下,true 活动能够及早完成。 在每次迭代完成之后,将计算 CompletionCondition

在大多数情况下,活动的泛型版本应该是首选解决方案,因为它涵盖了使用活动的大部分方案,并在编译时提供类型检查。 非泛型版本可用于循环访问实现非泛型 IEnumerable 接口的类型。

类定义

下面的代码示例演示非泛型 ParallelForEach 活动的定义。

[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; }
}

正文(可选)
ActivityAction 类型的 Object,将对集合中的每个元素执行它。 每个单个元素通过其 Argument 属性传递到 Body 中。

Values(可选)
循环访问的元素集合。 确保集合的所有元素在运行时都属于兼容类型。

CompletionCondition(可选)
在任何迭代完成后,对 CompletionCondition 属性进行评估。 如果计算结果为 true,则会取消计划的待处理迭代。 如果未设置此属性,分支集合中的所有活动将执行至完成为止。

使用 ParallelForEach 的示例

以下代码演示如何在应用程序中使用 ParallelForEach 活动。

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<T> 活动提供的设计器的外观相似。 设计器显示在“示例非泛型活动”类别的工具箱中。 此设计器在工具箱中命名为“ParallelForEachWithBodyFactory”,因为该活动在工具箱中公开了一个 ,后者使用正确配置的 IActivityTemplateFactory 创建活动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"
                }
            }
        };
    }
}

运行示例

  1. 将所选项目设置为解决方案的启动项目。

    1. CodeTestClient 演示如何使用代码来使用活动。

    2. DesignerTestClient 演示如何使用设计器中的活动。

  2. 生成并运行该项目。