Non-generic 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.

Значения (необязательно)
Коллекция элементов, по которой выполняется проход. Проверка совместимости типов для всех элементов коллекции проводится во время выполнения.

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. Постройте и запустите проект.