2015-01-31 3 views
1

처음으로 파일을 처리하는 곳에서 Parallel.ForEach을 사용하고 있습니다. WinForms 애플 리케이션의 맥락에서.타이머를 사용하여 Parallel.ForEach 측정을 예기치 않게 멈 춥니 다.

이 코딩 문제 (Parallel.ForEach 진행보고)에 대한 다른 스레드의 지침에 따라 병렬 코드가 포함 된 클래스의 public (int) 카운터 속성이 있으며 성공적으로 업데이트되고 있습니다. 주기적으로 카운터를 읽는 Timer도 있습니다.

병렬 코드를 실행하면 보이는 진행률 업데이트가 중지 된 것으로 보이고 병렬 코드가 완료되면 바로 시작됩니다.

FYI - 필자는 병렬 코드를 직접 호출합니다. 즉, 백그라운드 작업자 또는 비동기 메소드가 아닙니다.

답변

1

Parallel.ForEach()을 UI 스레드에서 호출하는 경우 (코드 예제가 없으므로 오류의 원인을 알 수있는 방법이 없음) 해당 메서드가 중지되고 모든 처리가 완료 될 때까지 기다리는 것이 UI 스레드는 a) 타이머 이벤트가 처리되는 것을 허용하고, b) 타이머가 처리 되더라도 UI가 업데이트되도록 허용하는 등의 다른 작업을 수행하지 못하게합니다.

Task.Run()에 대한 호출에서 Parallel.ForEach()의 호출을 감싸는 것이 하나의 가능한 접근 방법입니다. 예를 들어 :

private async void button1_Click(object sender, EventArgs e) 
{ 
    // some stuff 

    await Task.Run(() => Parallel.ForEach(...)); 

    // some other stuff 
} 

은 또는, 당신은 단지 개별 작업으로 전체를 실행할 수 있습니다 : 질문의 코드 예제없는 방법으로이 없기 때문에

private async void button1_Click(object sender, EventArgs e) 
{ 
    // some stuff 

    List<Task> tasks = new List<Task>(); 

    foreach (...) 
    { 
     tasks.Add(Task.Run(() => ...)); 
    } 

    await Task.WhenAll(tasks); 

    // some other stuff 
} 

은 (위의 예는, 세부 사항을 생략 실제로 거기에 갈 것이 무엇인지를 아십시오).

어떤 방법을 사용하면 처리가 진행되는 동안 진행 상황을 처리하기 위해 UI 스레드를 확보해야합니다.

+0

환호성 Peter & Yorye, 저 선을 따라 작업하겠습니다. –

+0

감사합니다. 비동기 메서드로 작업하고 기다리고 있습니다 (첫 번째 코드 블록과 비슷합니다). 나는 이것이 어떻게 진행되는지 그리고 필요할 때마다 리펙터를 볼 것입니다. –

4

Parallel.ForEach은 실제로 쿼리를 병렬 방식으로 평가하지만 실행 완료를 기다리고 호출 스레드를 차단합니다.

UI를 차단하지 않고 진행 변수를 업데이트하려면 별도의 스레드/백그라운드 작업자/작업에 사용해야합니다.