Inne niż ogólne ParallelForEach
Program .NET Framework 4.6.1 jest dostarczany w przyborniku zestaw działań przepływu sterowania, w tym ParallelForEach<T>, który umożliwia iterowanie za pośrednictwem IEnumerable<T> kolekcji.
ParallelForEach<T> wymaga, aby jego Values właściwość był typu IEnumerable<T>. Uniemożliwia to użytkownikom iterowanie struktur danych implementujących IEnumerable<T> interfejs (na przykład ArrayList). Wersja niegeneryczna ParallelForEach<T> rozwiązania tego wymagania, kosztem większej złożoności czasu wykonywania w celu zapewnienia zgodności typów wartości w kolekcji.
Przykład NonGenericParallelForEach pokazuje, jak zaimplementować działanie niegeneryczne ParallelForEach<T> i jego projektanta. To działanie może służyć do iterowania za pomocą ArrayListfunkcji .
Działanie ParallelForEach
Instrukcja języka C#/Visual Basic foreach
wylicza elementy kolekcji, wykonując osadzoną instrukcję dla każdego elementu kolekcji. Równoważne działania WF to ForEach<T> i ParallelForEach<T>. Działanie ForEach<T> zawiera listę wartości i treść. W czasie wykonywania lista jest iterowana, a treść jest wykonywana dla każdej wartości na liście.
ParallelForEach<T>CompletionConditionelement ma wartość , aby ParallelForEach<T> działanie mogło zostać ukończone wcześnie, jeśli ocena CompletionCondition zwraca wartość true
. Wartość jest obliczana CompletionCondition po zakończeniu każdej iteracji.
W większości przypadków ogólna wersja działania powinna być preferowanym rozwiązaniem, ponieważ obejmuje większość scenariuszy, w których jest używana, i zapewnia sprawdzanie typów w czasie kompilacji. Wersja niegeneryczna może służyć do iterowania za pośrednictwem typów, które implementują interfejs niegeneryczny IEnumerable .
Definicja klasy
Poniższy przykład kodu przedstawia definicję działania niegenerykowego 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; }
}
Treść (opcjonalnie)
ObjectTyp ActivityAction , który jest wykonywany dla każdego elementu w kolekcji. Każdy pojedynczy element jest przekazywany do właściwości Body za pośrednictwem właściwości Argument.
Wartości (opcjonalnie)
Kolekcja elementów, które są iterowane. Zapewnienie, że wszystkie elementy kolekcji są zgodne typy, są wykonywane w czasie wykonywania.
CompletionCondition (opcjonalnie)
Właściwość CompletionCondition jest oceniana po zakończeniu iteracji. Jeśli zostanie obliczona wartość true
, zaplanowane iteracje oczekujące zostaną anulowane. Jeśli ta właściwość nie jest ustawiona, wszystkie działania w kolekcji Gałęzie są wykonywane do momentu ukończenia.
Przykład użycia metody ParallelForEach
Poniższy kod pokazuje, jak używać działania ParallelForEach w aplikacji.
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 Designer
Projektant działań dla przykładu jest podobny do projektanta udostępnionego dla wbudowanego ParallelForEach<T> działania. Projektant zostanie wyświetlony w przyborniku w kategorii Przykłady, działania inne niż ogólne . Projektant ma nazwę ParallelForEachWithBodyFactory w przyborniku, ponieważ działanie uwidacznia IActivityTemplateFactory element w przyborniku, który tworzy działanie z prawidłowo skonfigurowanym ActivityActionelementem .
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"
}
}
};
}
}
Aby uruchomić przykład
Ustaw wybrany projekt jako projekt startowy rozwiązania.
CodeTestClient pokazuje, jak używać działania przy użyciu kodu.
Projektant TestClient pokazuje, jak używać działania w projektancie.
Skompiluj i uruchom projekt.