Parallel.ForEach с условиями - PullRequest
       35

Parallel.ForEach с условиями

0 голосов
/ 28 февраля 2019

У меня есть список объектов.Объект является экземпляром класса.Внутри каждого объекта есть свойство, которое содержит какое-то значение:

List<SomeClassTask> lstSomeTaskList = new List<SomeClassTask>();

for (int i=0; i<5; i++)
{
     SomeClassTask tsk = new SomeClassTask();
     Thread.Sleep(500);
     tsk.SomeProperty = new Random().Next(1, 11);

     lstSomeTaskList.Add(tsk);
}

Следующим шагом является запуск параллельной задачи для каждого объекта

Parallel.ForEach(lstSomeTaskList, task => task.StartProcessing(task.SomeProperty));

Я хочу запускать только определенные задачи, такие как задача, которая имеетзначение 1 (SomeProperty = 1).

Это класс:

class SomeClassTask
{
    public int SomeProperty { get; set; }
    public void StartProcessing(int maxRange)
    {
        int rnd = new Random().Next(1, maxRange);
        Thread.Sleep(1000);
        Console.WriteLine("Parallel task -> radnom created value: " + rnd);
    }
}

Возможно ли это внутри

Parallel.ForEach

поставить некоторые условия для проверки некоторых свойств объекта?

Ответы [ 2 ]

0 голосов
/ 28 февраля 2019

Вы должны использовать Microsoft Reactive Framework (он же Rx) - NuGet System.Reactive и добавить using System.Reactive.Linq; - тогда вы можете сделать это:

IObservable<SomeClassTask> query =
    from i in Observable.Range(0, 5)
    let tsk = new SomeClassTask() { SomeProperty = _random.Next(1, 11) }
    where tsk.SomeProperty == 1
    from u in Observable.Start(() => tsk.StartProcessing(tsk.SomeProperty))
    select tsk;

IDisposable subscription = query.Subscribe();

Теперь, если вам нужны все результаты, когдазапрос завершен, тогда сделайте следующее:

IDisposable subscription =
    query
        .ToList()
        .Subscribe(list => { /* use `list` here */ });

Если вам нужно завершить процесс до его завершения, просто выполните subscription.Dispose();.

0 голосов
/ 28 февраля 2019

Parallel.ForEach Получает IEnummerable в качестве источника, поэтому вам просто нужно отфильтровать объект списка и передать его в ForEach, что-то вроде:

SomeClassTask a = new SomeClassTask { SomeProperty = 1 };
SomeClassTask b = new SomeClassTask { SomeProperty = 2 };

List<SomeClassTask> lstSomeTaskList = new List<SomeClassTask> { a, b };

Parallel.ForEach(lstSomeTaskList.Where(task => task.SomeProperty == 1),
task => task.StartProcessing(task.SomeProperty));

Редактировать
Как уже отмечалось в комментариях, вы должны проверить это -> https://codeblog.jonskeet.uk/2009/11/04/revisiting-randomness/

...