Разрыв параллельный.

Как вырваться из цикла parallel.for?

У меня довольно сложное выражение, которое выглядит следующим образом:

Parallel.ForEach<ColorIndexHolder>(ColorIndex.AsEnumerable(),
    new Action<ColorIndexHolder>((ColorIndexHolder Element) =>
    {
        if (Element.StartIndex <= I && Element.StartIndex + Element.Length >= I)
        {
            Found = true;
            break;
        }
    }));

Используя параллельный класс, я могу оптимизировать этот процесс на сегодняшний день. Однако; Я не могу понять, как разбить параллельный цикл? Оператор break; выдает следующую синтаксическую ошибку:

Отсутствуют замкнутые контуры, из которых можно сломать или продолжить

Ответ 1

Используйте метод ParallelLoopState.Break:

 Parallel.ForEach(list,
    (i, state) =>
    {
       state.Break();
    });

Или в вашем случае:

Parallel.ForEach<ColorIndexHolder>(ColorIndex.AsEnumerable(),
    new Action<ColorIndexHolder, ParallelLoopState>((ColorIndexHolder Element, ParallelLoopState state) =>
    {
        if (Element.StartIndex <= I && Element.StartIndex + Element.Length >= I)
        {
            Found = true;
            state.Break();
        }
    }));

Ответ 2

Вы делаете это, вызывая использование перегрузки Parallel.For или Parallel.ForEach, которая проходит в состоянии цикла, а затем вызывает ParallelLoopState.Break или ParallelLoopState.Stop. Основное различие заключается в том, как быстро вещи ломаются - с Break(), цикл будет обрабатывать все элементы с более ранним "индексом", чем текущий. С помощью Stop() он выйдет как можно быстрее.

Подробнее см. Практическое руководство. Стоп или разрыв с Parallel.For Loop.

Ответ 3

То, что вы должны использовать, это Any, а не цикл foreach:

bool Found = ColorIndex.AsEnumerable().AsParallel()
    .Any(Element => Element.StartIndex <= I 
      && Element.StartIndex + Element.Length >= I);

Any достаточно умен, чтобы остановить, как только он узнает, что результат должен быть правдой.

Ответ 4

Просто используйте loopState, который может быть предоставлен.

Parallel.ForEach<ColorIndexHolder>(ColorIndex.AsEnumerable(),  
    new Action<ColorIndexHolder>((Element, loopState) => { 
        if (Element.StartIndex <= I && Element.StartIndex + Element.Length >= I) { 
            loopState.Stop();
        }     
})); 

Посмотрите на статью MSDN для примера.

Ответ 5

LoopState - отличный ответ. Я нашел, что в предыдущих ответах было так много других вещей, что было трудно увидеть ответ, так что вот простой случай:

using System.Threading.Tasks;

Parallel.ForEach(SomeTable.Rows(), (row, loopState) =>
{
    if (row.Value == testValue)
    {
        loopState.Stop();  // Stop the ForEach!
    }       
    // else do some other stuff here.
});