非ジェネリックの ParallelForEach

.NET Framework 4.6.1 のツールボックスには、制御フロー アクティビティのセットが用意されています。これには、IEnumerable<T> コレクションを反復処理できる ParallelForEach<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; }
}

Body (省略可能)
コレクション内の要素ごとに実行される 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 です。これは、適切に構成された ActivityAction を使用してアクティビティを作成する IActivityTemplateFactory がツールボックスでアクティビティによって公開されるためです。

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. プロジェクトをビルドして実行します。