Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
.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; }
}
Текст (необязательно)
Тип ActivityActionObject, который выполняется для каждого элемента в коллекции. Каждый отдельный элемент передается в Body через его свойство Argument.
Значения (необязательно)
Коллекция элементов, перебираемых в процессе итерации. Обеспечение того, чтобы все элементы коллекции были совместимы по типу в процессе выполнения.
Условие завершения (необязательно)
Свойство 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"
}
}
};
}
}
Запуск примера
Задайте выбранный проект в качестве запускаемого проекта решения.
CodeTestClient показывает, как использовать действие с помощью кода.
DesignerTestClient показывает, как использовать активность в конструкторе.
Соберите проект и запустите его.