2013-05-04 2 views
1

현재 작업을 사용하여 .Net 4.0에서 병렬 스레딩을 사용하여 성능 최적화를 수행하려고합니다.System.Threading.Tasks 동작 이해

일부 개체 또는 개체의 컬렉션을 반환하는 세 가지 메서드를 만들었습니다. MethodA, MethodB 및 MethodC를 호출 할 수 있습니다.

나는 약 5 ~ 7 초 정도의 지연이 있습니다.

var person = new Person(); 

person.A = Task.Factory.StartNew(() => Mystatic.MethodA()).Result; 
person.B = Task.Factory.StartNew(() => Mystatic.MethodB()).Result; 
person.C = Task.Factory.StartNew(() => Mystatic.MethodC()).Result; 

지금은 기대하고 person.A 및 person.C 속성은 person.B 전에 채워/설정,하지만 난 어려움이있을 수 내 가정을 확인하기 위해 디버깅 테스트 /.

세 가지 속성 모두에 대해 병렬 감시를 추가했지만 디버깅을 통해 문제가 해결되지 않았습니다.

또한 주 개체를 채우는 경우 메서드 호출을 여러 번 최적화 할 수있는 적절한 방법입니까?

제 경우에는 데이터를 수집하는 데 5 ~ 7 가지의 다른 방법이 있는데, 그 중 일부는 비교적 시간이 많이 걸리는 것처럼 병렬 처리하고 싶습니다.

+1

사이드 노트 :'Task.Factory.StartNew'라고 적어주세요. – usr

+0

니스 - 그게 훨씬 간단합니다 :) – codingjoe

답변

1

귀하의 가정이 잘못되었습니다. 작업의 Result 속성은 작업이 완료 될 때까지 실제로 대기합니다. 따라서 A, B, C가 순서대로 지정됩니다. 또한 비동기 작업 생성의 목적을 무효화합니다.

한 가지 방법은 당신이 A, B 각 작업의 결과를 할당 모든 세 가지 작업에 Task.WaitAll을 사용할 수 있습니다 C

입니다

당신은 또한 당신이 VS2012이있는 경우 비동기가/await를 사용할 수 있습니다 - 당신은 여전히 ​​수 - 당신은 어느 정도 병렬 실행을 원하는 경우

person.A = await Task.Run(() => Mystatic.MethodA()); 
person.B = await Task.Run(() => Mystatic.MethodB()); 
person.C = await Task.Run(() => Mystatic.MethodC()); 

여전히 순차적 될 것입니다 : 그러나 당신이 할 경우 그 비동기/await를 병렬로 3 작업을 시작하지 않습니다 이해 http://nuget.org/packages/Microsoft.Bcl.Async/

를 사용하여 .NET 4.0을 대상으로 당신은 이것을 할 수 있습니다 :

Task tA = Task.Run(() => Mystatic.MethodA()); 
Task tB = Task.Run(() => Mystatic.MethodB()); 
Task tC = Task.Run(() => Mystatic.MethodC()); 

person.A = await tA; 
person.B = await tB; 
person.C = await tC; 
+0

그래, 동료들에 의해 설명 된 부분이 있습니다. 내 관심사는 단지 개별 스레드가 병렬로 작업하고 있다는 것입니다. 순차적이지 않다. – codingjoe

4

타이밍은 항상 보장되지 않기 때문에 원칙적으로 타이밍에 의존하고 있습니다. 특히 실제 단어 조건에서는 그렇지 않습니다. 작업이 완료되었는지 확인하려면 대기을 적용해야합니다. 또는 C# 5.0 async-await 또는 continuations을 사용하십시오.

즉, 우연히 프로그램하지 마십시오. 구성하여 프로그램을 수정하십시오.

+0

+1. 만약 객체가 생성 후에 (오랜) 초기화가 필요하다면,'public static Task CreateAsync()'메소드를 포함시키고 (아마도) 생성자를 private으로 만들 것입니다. 하지만 나는 빗나갑니다 : –

+0

이것은 정답입니다. 그러나 만약 당신이 정말로 디버거 (의문의 여지)를 사용하여 당신의 의심을 시험하기를 원한다면, 각 속성 세터에서 간단한 Debug.Write를 할 수도 있고, 아니면 각 세터에 중단 점을 설정할 수도 있습니다. – Gjeltema

+0

디버깅을 통해 나는 각 속성에 시계를 만들었고 스코프 끝 부분에 중단 점을 설정하고 시계를 주시했습니다. 나는 await/async 실험을 시도 할 것이지만 현재 사용하고있는 프레임 작업 버전에는 없습니다. ( – codingjoe