parallel.foreach를 중단 하시겠습니까?


111

어떻게 밖으로 휴식 할 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
루프의 모든 병렬 인스턴스가 동시에 중단 될 것으로 예상하십니까?
n8wrl 2012 년

답변:


185

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();
        }
    }));

바로 그거죠. 직접 게시하려고했습니다.
Mare Infinitus 2012 년

1
순차 foreach 루프를 생각하면 어떤 이유로 든 중단을 일으킨 항목 이전의 항목이 처리된다는 것이 보장됩니다. 항목의 순서가 반드시 처리되는 순서 일 필요는없는 Parallel.ForEach는 어떻습니까? state.Break ()를 호출하는 항목 이전에 IEnumerable <...>의 모든 항목이 처리되고 그 이후에 오는 항목은 처리되지 않는 것이 보장됩니까? 전자는 어떻게 든 달성 할 수 있었지만 후자가 어떻게 가능할지는 전혀 모르겠습니다.
Hendrik Wiese 2013 년

4
@Hendrik 비제 : 문서 말 : Calling the Break method informs the for operation that iterations after the current one don't have to execute. However, all iterations before the current one will still have to be executed if they haven't already.there is no guarantee that iterations after the current one will definitely not execute.
튜더

2
그럼 것 state.Stop()마이크 Perrenoud 및 MBentley 아래 언급 한 바와 같이, 안정적으로 예상되는 결과를 달성하는 것이 더 적합 할
xtreampb

44

당신의 과부하 사용하여 호출하여이 작업을 수행 Parallel.For하거나 Parallel.ForEach루프 상태에 전달하는 다음 호출 ParallelLoopState.Break또는 ParallelLoopState.Stop. 가장 큰 차이점은 사물이 얼마나 빨리 깨지는 지에 있습니다 Break(). 루프는 현재보다 더 이른 "인덱스"를 가진 모든 항목을 처리합니다. 를 사용하면 Stop()가능한 한 빨리 종료됩니다.

자세한 내용은 방법 : Parallel.For 루프에서 중지 또는 중단을 참조하십시오 .


3
+1, 여기에있는 우리 중 일부는 똑같은 대답을 가지고있는 것 같습니다. :)-아, 그리고 다른 댓글에 대한 지원을 받았습니다.
Mike Perrenoud

이 설명에 감사드립니다. break 또는 stop이 언제 호출되는지 알고 있습니까? 현재 실행중인 반복이 완료된 경우입니까, 아니면 실행 도중에 반복을 중지합니까?
CeejeeB

1
@CeejeeB 현재 실행중인 작업이 완료되었습니다.
Reed Copsey

12

당신이 사용해야 Any하는 것은 foreach 루프가 아니라입니다 :

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

Any 결과가 사실이어야한다는 사실을 알게되는 즉시 멈출 수있을만큼 똑똑합니다.


10

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.
});

5

loopState제공 할 수 있는 것을 사용하십시오 .

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

예제 는이 MSDN 문서참조하십시오 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.