2011-11-17 6 views
8

데이터 테이블에 요약 항목이 가득 찼습니다. 내 소프트웨어는 세부 사항을 확인하기 위해 웹 서비스로 이동하여 데이터베이스에 기록해야합니다. 웹 서비스를 호출하고 응답을 기다리는 동안 테이블을 동 기적으로 반복하면 너무 느려서 (수천 개의 항목이 있습니다) 결과 (10 개 정도)를 취하고 스레드를 실행하여 10을 수행하고 싶습니다. 동시에 작업.데이터베이스 큐에 대한 스레드 풀을 관리하는 가장 좋은 방법

C# 스레드에 대한 경험이 제한적이므로 최선의 방법은 무엇입니까? .NET에는 결과가 적절하게 그리고 순서대로 처리되도록하기 위해 사용할 수있는 일종의 threadsafe 큐 시스템이 있습니까?

+2

.Net의 버전은 무엇입니까? 닷넷 4의 멀티 쓰레드 프로그래밍에는 큰 발전이있었습니다. – svick

+0

그 중 하나가 포함되어 있어야합니다. 현재 3.5를 목표로하고 있지만,별로 문제없이 4.0으로 갈 수 있습니다. –

답변

5

.NET Framework의 버전에 따라 두 가지 옵션이 있습니다.

ThreadPool.QueueUserWorkItem을 모든 버전에서 사용할 수 있습니다.

int pending = table.Rows.Count; 
var finished = new ManualResetEvent(false); 
foreach (DataRow row in table.Rows) 
{ 
    DataRow capture = row; // Required to close over the loop variable correctly. 
    ThreadPool.QueueUserWorkItem(
    (state) => 
    { 
     try 
     { 
     ProcessDataRow(capture); 
     } 
     finally 
     { 
     if (Interlocked.Decrement(ref pending) == 0) 
     { 
      finished.Set(); // Signal completion of all work items. 
     } 
     } 
    }, null); 
} 
finished.WaitOne(); // Wait for all work items to complete. 

.NET Framework 4.0을 사용하는 경우 Task Parallel Library을 사용할 수 있습니다.

var tasks = new List<Task>(); 
foreach (DataRow row in table.Rows) 
{ 
    DataRow capture = row; // Required to close over the loop variable correctly. 
    tasks.Add(
    Task.Factory.StartNew(
    () => 
     { 
     ProcessDataRow(capture);   
     })); 
} 
Task.WaitAll(tasks.ToArray()); // Wait for all work items to complete. 

다른 많은 합리적인 방법이 있습니다. 위에서 패턴을 강조 표시하는 것은 쉽고 잘 작동하기 때문입니다. 특정 세부 사항이 없으면 어느 것이 든 당신의 상황에 완벽하게 어울리는다고 말할 수는 없지만 좋은 출발점이되어야합니다.

는 업데이트 :

나는 평균 이하 뇌 활동의 짧은 기간을 가지고 있었다. TPL을 사용할 수 있다면 위에 언급 한 Task hocus-pocus보다 간단한 방법으로 Parallel.ForEach을 사용할 수도 있습니다.

Parallel.ForEach(table.Rows, 
    (DataRow row) => 
    { 
    ProcessDataRow(row); 
    }); 
+0

그런데 Microsoft 웹 사이트에서 Reactive Extensions 백 포트를 다운로드하면 3.5에서 TPL을 실제로 사용할 수 있습니다. –

+0

굉장한 물건 - 모두에게 많은 감사합니다. 이 고양이를 껍질을 벗기는 여러 가지 방법이있는 것처럼 보입니다! –

+0

한 가지만 (내가 알기 론, 나는 RTFM으로 갈 것입니다!), 그러나이 스케일은 어떻게됩니까? 나는 수천 개의 행을 처리 할 것이고, 수천 개의 스레드를 동시에 시작하고 싶지는 않을 것입니다. 나는 추측하고있다 (희망적 이냐?) 일종의 제한이 내장되어있어 사용자의 컴퓨터가 멈추지 않습니다. –

5

.NET에는 결과가 올바르게 처리되고 순서대로 처리되도록하는 데 사용할 수있는 일종의 스레드 안전 큐 시스템이 있습니까?

이것은 .NET 4에 추가 된 것입니다. BlockingCollection<T> 클래스는 기본적으로 제작자/소비자 시나리오의 스레드 안전 큐 역할을합니다.

하나 이상의 요소가 컬렉션에 추가되면서 컬렉션 및 프로세스에서 "소비"하는 요소를 쉽게 생성 할 수 있습니다.

+0

아주 좋아, 나는 그것을 확실히 체크 아웃 할 것이다. 감사! –

+0

동시 대기열은 어떻게됩니까? http://msdn.microsoft.com/en-us/library/dd267265.aspx? – Dykam

+0

@Dykam'BlockingCollection '은 기본적으로'ConcurrentQueue '을 래핑합니다. CQ를 직접 사용할 수 있지만 설명 된대로 제작자/고객 시나리오에서 작업하려면 BC가 훨씬 간단합니다. –

관련 문제