1

parallel.foreach을 사용할 때 특정 스레드를 취소 할 수있는 방법이 있습니까?parallel.foreach를 반복 할 때 스레드를 하나만 취소 할 수 있습니까?

cancelToken.token을 사용하여 모든 스레드를 취소 할 수 있다는 것을 알고 있는데, parallelOptions()을 사용하여 어떻게 처리합니까? 특정 스레드을 어떻게 취소 할 수 있습니까?

parallel.foreach 대신 스레드 목록을 작성하는 경우 취소 할 스레드를 선택하는 데 문제가 없지만 모든 프로그램을 병렬로 실행해야하며 비동기로 실행하지 않아야합니다. 내 CPU 및 단순히 CPU 리소스를 슬라이스).

+2

실제로 달성하려는 내용을 설명해 주시겠습니까? 스레드 또는 루프 반복을 중지 하시겠습니까? 정말로 스레드라면, 왜? 'Parallel.ForEach'는 대부분 당신을 위해 쓰레드를 관리합니다. 그렇게 할 필요는 없습니다. – svick

답변

1

Parallel 클래스는 ThreadPool을 사용하여 작업을 대기열에 넣고 실행합니다.

질문에 대답하기 위해 특정 "스레드"를 취소 할 수있는 방법이 있다고 생각하지 않지만 취소 토큰을 사용하지 않고 Parallel.For에서 중단 할 수 있습니다.

MSDN에서 다음을 참조하십시오. 방법 : Stop or Break from a Parallel.For Loop.

3

편집 : 좋아, 내 첫번째 생각은 나쁜했지만,이 작품 :

List<string> Items = new List<string>() 
{ 
    "First", 
    "Second", 
    "Third", 
    "Fourth" 
}; 

Parallel.ForEach(Items, (s, t) => 
{ 
    if (s == "Second") 
     return; 
    Console.WriteLine(s); 
}); 

내가 그 비주얼 스튜디오를 기다리지 않고 답변을 발사 가르쳐 것 같아요 교훈을 배웠습니다 : P

+0

아니요, Parallel.ForEeach에서 계속을 사용할 수 없습니다. 동등한 함수는 ['Action' overload] (https://msdn.microsoft.com/en-us/library/dd991604)를 사용했는지에 따라 body 함수에서'return;'또는'return local;'을 호출하는 것일뿐입니다. (v = vs.110) .aspx) 또는 ['Func' overload (https://msdn.microsoft.com/en-us/library/dd783634(v=vs.110) .aspx). –

+0

감사합니다. VS를 실행하자마자 Parallel.ForEach에 서명이 있음을 기억했습니다. 잘못된 방향으로 유감스럽게 생각합니다. – BenAlabaster

2

William Xifaras 이미 언급했듯이 Parallel.Foreach 또는 Parallel.For을 사용하면 코드를 실행하는 데 ThreadPool이 사용됩니다.

Task<T>을 사용하여 이와 유사한 기능을 작성하지만 이와 같이 취소하는 이유는 무엇입니까?

 Action<CancellationToken> work = (token) => 
     { 
      Console.WriteLine($"Work started on Thread: {Thread.CurrentThread.ManagedThreadId}"); 
      foreach (var i in Enumerable.Range(0, 10)) 
      { 
       if (token.IsCancellationRequested) 
       { 
        Console.WriteLine($"Work cancelled on Thread: {Thread.CurrentThread.ManagedThreadId}"); 
        return; 
       } 
       Thread.Sleep(1000); 
      } 
      Console.WriteLine($"Work complete on Thread: {Thread.CurrentThread.ManagedThreadId}"); 
     }; 

     var tasks = new List<Tuple<Task, CancellationTokenSource>>(); 

     foreach (var i in Enumerable.Range(0, 4)) 
     { 
      var cancellation = new CancellationTokenSource(); 
      var task = Task.Run(() => work(cancellation.Token), cancellation.Token); 
      tasks.Add(new Tuple<Task, CancellationTokenSource>(task, cancellation)); 
     } 

     tasks.First().Item2.Cancel(); 
     Task.WaitAll(tasks.Select(m => m.Item1).ToArray()); 

이 비슷한 출력을 생성합니다 :

Work started on Thread: 3 
Work started on Thread: 6 
Work started on Thread: 4 
Work started on Thread: 5 
Work cancelled on Thread: 3 
Work complete on Thread: 6 
Work complete on Thread: 5 
Work complete on Thread: 4 

이 당신이 달성하려고 무엇입니까?