ParallelForEach non générique

.NET Framework 4.6.1 fournit, dans sa boîte à outils, un ensemble d’activités de flux de contrôle, dont ParallelForEach<T> qui permet l’itération au sein de collections IEnumerable<T>.

ParallelForEach<T> requiert que sa propriété Values soit de type IEnumerable<T>. Cela empêche les utilisateurs d'itérer au sein des structures de données qui implémentent l'interface IEnumerable<T> (par exemple, ArrayList). La version non générique de ParallelForEach<T> passe outre cette exigence, aux dépens d’un runtime plus complexe afin de garantir la compatibilité des types des valeurs dans la collection.

L’ échantillon NonGenericParallelForEach montre comment implémenter une activité ParallelForEach<T> non générique et son concepteur. Cette activité peut être utilisée pour itérer au sein de ArrayList.

Activité ParallelForEach

L’instruction C#/Visual Basic foreach énumère les éléments d’une collection, exécutant une instruction incorporée pour chaque élément de la collection. Les activités WF équivalentes sont ForEach<T> et ParallelForEach<T>. L'activité ForEach<T> contient une liste de valeurs et un corps. Au moment de l’exécution, la liste est soumise à une itération et le corps est exécuté pour chacune des valeurs qu’elle contient.

ParallelForEach<T> a un CompletionCondition afin que l'activité ParallelForEach<T> puisse se terminer tôt si l'évaluation du CompletionCondition retourne la valeur true. Le CompletionCondition est évalué à l'issue de chaque itération.

Dans la plupart des cas, la version générique de l'activité doit être la solution par défaut, car elle couvre la plupart des scénarios dans lesquels elle est utilisée, et fournit la vérification des types au moment de la compilation. La version non générique peut être utilisée pour itérer au sein de types qui implémentent l'interface IEnumerable non générique.

Définition de classe

L'exemple de code suivant illustre la définition d'une activité ParallelForEach non générique.

[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 (facultatif)
ActivityAction de type Object, qui est exécuté pour chaque élément de la collection. Chaque élément individuel est passé dans le corps (Body) via sa propriété Argument.

Values (facultatif)
Collection des éléments sur lesquels est effectuée l’itération. La vérification que tous les éléments de la collection sont de types compatibles est effectuée au moment de l'exécution.

CompletionCondition (facultatif)
La propriété CompletionCondition est évaluée à l'issue de toute itération. Si sa valeur est true, les itérations en attente planifiées sont annulées. Si cette propriété n’est pas définie, toutes les activités de la collection Branches s’exécutent jusqu’à la fin.

Exemple d’utilisation de ParallelForEach

Le code suivant montre comment utiliser l'activité ParallelForEach dans une 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)))
           }
       }
   };

Concepteur ParallelForEach

Le concepteur d'activités de l'exemple est semblable, en apparence, au concepteur fourni pour l'activité ParallelForEach<T> intégrée. Le concepteur s’affiche dans la boîte à outils dans la catégorie Exemples, Activités non génériques. Le concepteur est nommé ParallelForEachWithBodyFactory dans la boîte à outils, car l’activité expose un IActivityTemplateFactory dans la boîte à outils, ce qui crée l’activité avec un ActivityAction correctement configuré.

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

Exécution de l'exemple

  1. Définissez le projet de votre choix comme projet de démarrage de la solution.

    1. CodeTestClient indique comment utiliser l’activité à l’aide du code.

    2. DesignerTestClient indique comment utiliser l’activité dans le concepteur.

  2. Générez et exécutez le projet.