2012-11-30 4 views
2

각 섹션에는 많은 계산 시간이 소요되는 데이터가 포함 된 애플리케이션이 있습니다. 나는이에 볼 수있는 몇 가지 방법이 있습니다 :지연 계산으로 사전 계산 혼합하기

  1. 간단한 해결책 1 : 응용 프로그램 시작에 모든 섹션의 데이터를 계산가. 이는 응용 프로그램 시작이 느려짐을 의미합니다.

  2. 간단한 해결책 2 : 사용자가 데이터를로드 할 때 각 섹션의 데이터를 계산하십시오. 즉, 각 섹션을로드하는 속도가 느려집니다 (각 섹션은 이미 상당한 렌더링 계산을 수행해야하므로 불량입니다.)

  3. 성능이이 응용 프로그램에 중요하므로이 두 가지 해결 방법은 이상적입니다. 따라서 간단하지 않은 해결책이 생깁니다 : 앱을 시작할 때 백그라운드 스레드에서 섹션 데이터 계산을 시작하십시오.이 솔루션의 문제점은 사용자가 어떤 섹션을 예측할 좋은 방법이없는 것입니다. 먼저로드합니다. 따라서 마지막 섹션을로드하여 백그라운드 스레드에로드하면 솔루션 2로 방금 갔을 때보 다 더 오래 기다릴 것입니다.

  4. 이렇게하면 해결책이 생깁니다 : ab에서 섹션 데이터 계산 시작 그러나 사용자가 섹션을로드하면 백그라운드 스레드를 일시 중지하고 사용자가 요청한 섹션에 대한 계산을 시작합니다. 계산이 이미 시작된 경우가 아니면 완료됩니다.

는 내가 가장 간단한 해결책은 그냥이 장전 작업의 우선 순위 최대 우선 순위 큐를 사용하는 아마 생각 솔루션 (4)을 구현하는 방법을 잘 모르겠어요,하지만 난 방법을 잘 모르겠어요 C#에서 이것을 구현하십시오. 이것은 합리적인 접근법입니까? C#의 우선 순위 대기열에는 어떤 훌륭한 라이브러리가 있습니까?

답변

0

Task<Section> 개체의 배열 (또는 원하는 경우 다른 데이터 구조)부터 시작하겠습니다.

private Task<Section>[] sections = new Task<Section>[5]; 

컬렉션이 만들어지고 실제로 응용 프로그램의 시작 부분에 백그라운드에서 정의 된 작업을 실제로 정의해야합니다.

for (int i = 0; i < sections.Length; i++) 
{ 
    int sectionNumber = i; //copy for closure 
    Task<Section> next = new Task<Section>(() => CreateSection(sectionNumber)); 
    //note the task isn't started. 
    sections[i] = next; 
} 

그런 다음 당신은 백그라운드 작업은 실제로 작업을 한 번에 하나씩 처리를 시작할 수 있습니다 : 당신이 항목에 대한 작업을 여러 스레드를 갖고 싶어

Task.Run(() => 
{ 
    for (int i = 0; i < sections.Length; i++) 
    { 
     EnsureStarted(sections[i]); 
     sections[i].Wait(); 
    } 
}); 

당신은 Parallel.For을 사용할 수 있습니다.당신이 (그 비 블로킹 버전이 필요하면

public Section GetFinishedSection(int sectionNumber) 
{ 
    EnsureStarted(sections[sectionNumber]); 
    return sections[sectionNumber].Result; 
} 

: (필요한 경우 시작)

public void EnsureStarted(Task task) 
{ 
    if (task.Status == TaskStatus.Created) 
    { 
     task.Start(); 
    } 
} 

그런 다음 실제로 완성 된 부분을 얻을 : 방법이 도우미 메서드를 사용하는

가능하면 await입니다) 다음과 같이 사용하십시오 :

public Task<Section> EnsureSectionComplete(int sectionNumber) 
{ 
    EnsureStarted(sections[sectionNumber]); 
    return sections[sectionNumber]; 
} 
1

해결책 4를 수정하면 백그라운드에서 각 섹션을로드 할 수 있습니다. 사용자가 섹션을 선택하면 새 스레드를 스핀 오프하지 않고 더 높은 우선 순위로 해당 섹션을로드하지 않으면 현재 주 스레드 큐에 의해로드되고 있는지 확인하십시오. 물론이 선택을 기본 작업 대기열에서 제거하려고합니다.

여기 MSDN에서 우선 순위를 설정하는 example입니다.

+0

que에서 다른 작업을 제거하는 대신 큐가 이미 작업을 시작하려고하는 항목이 이미 완료되었는지 확인하는 것이 더 쉬울 수도 있습니다. 동일한 결과이지만 구현하기 쉽습니다. – Servy