0

100K 항목이 포함 된 동시 수집이 있습니다. 컬렉션의 각 항목 처리에는 최소 100ms 또는 최대 10 초가 소요될 수 있습니다. 프로세싱을 병렬화하여 작업 속도를 높이고 동시에 작업을 수행하는 100 명의 미니언을 원합니다. 이 처리가 발생하면 UI에 일부 특정 데이터를보고해야합니다. 단순히 완료되는 비율이 아닙니다.동시 작업, 병렬 작업시 사용자 지정 진행률 데이터를 UI로보고

병렬 처리 된 하위 작업이 연못에 버려진 빵 조각을 공격하는 미성년자 학교와 같은 동시 수집에서 나눠지기를 바란다. 동시 수집을 병렬화 된 태스크에 어떻게 표시합니까? 정상적인 루프를 가질 수 있고 단순히 루프 내에서 비동기 태스크를 실행하고 IProgress를 전달할 수 있습니까? 이 경우에도 동시 수집이 필요합니까?

Parallel.ForEach를 사용하는 것이 좋지만 병렬 처리 수준으로 설정된 각 하위 프로세스가 사용자 지정 개체를 UI에 다시보고 할 수있는 방법이 표시되지 않습니다. 항목이 처리되며, 100K 항목의 점유율을 처리 한 후에뿐만 아니라

답변

0

이 프레임 워크는 이미이 목적으로 IProgress 인터페이스를 제공하고 구현은 Progress에 제공합니다. 진행 상황을보고하려면 진행 값으로 IProgress.Report으로 전화하십시오. T 값은 숫자가 아닌 모든 유형이 될 수 있습니다.

각 IProgress 구현은 고유 한 방식으로 작동 할 수 있습니다. Progress는 이벤트를 발생시키고 이벤트를 생성 할 때 전달하는 콜백을 호출합니다.

또한 Progress.Report는 비동기 적으로 실행됩니다. 여기에서는 SychronizationContext.Post을 사용하여 Progress 인스턴스를 만든 스레드에서 콜백 및 모든 이벤트 처리기를 실행합니다.

이 같은 진행 값 클래스를 만들 가정 :

class ProgressValue 
{ 
    public long Step{get;set;} 
    public string Message {get;set;} 
} 

당신이 뭔가를 작성할 수

IProgress<ProgressValue> myProgress=new Progress<ProgressValue>(p=> 
{ 
    myProgressBar.Value=p.Step; 
}); 

IList<int> myVeryLargeList=...; 
Parallel.ForEach(myVeryLargeList,item,state,step=> 
{ 
    //Do some heavy work 
    myProgress.Report(new ProgressValue 
    { 
     Step=step, 
     Message=String.Format("Processed step {0}",step); 
    }); 
}); 

편집

아차! 진행은 IProgress를 명시 적으로 구현합니다. @Tim이 알아 챘 듯이 IProgress로 전송해야합니다.

myProgress를 IProgress로 명시 적으로 선언하는 코드가 수정되었습니다.

+0

답장과 샘플 코드를 보내 주셔서 감사합니다. – Tim

+0

"무거운 작업"은 동기식 방법 일 수 있습니까? Parallel.ForEach 내부에서 비동기 메소드를 기다릴 수 있습니까? – Tim

+0

Parallel.Foreach는 많은 양의 데이터에 대해 동시 작업을 병렬로 실행하도록 만들어졌습니다. Parallel.Foreach는 람다 선언 전에'async' 키워드를 추가함으로써 Parallel.ForEach 내부에서 기다릴 수 있습니다.하지만 Parallel.Foreach는 결국 태스크를 생성하고 기다리게됩니다. 더 나은 솔루션은 병렬 단계의 파이프 라인을 사용하여 이전 단계에서 생성 된 데이터를 처리하는 것입니다. TPL 데이터 흐름은이 구현 중 하나입니다 –