2011-11-17 32 views
8

我有一個充滿總結條目的數據表,我的軟件需要通過並訪問Web服務以獲取詳細信息,然後將這些詳細信息記錄回數據庫。在調用Web服務並等待響應時同步循環訪問表(因爲有成千上萬的條目),所以我想要將結果(每次10個左右)結果並進行線程處理,以便執行10操作同時進行。管理針對數據庫隊列的線程池的最佳方法

我對C#線程的經驗僅限於說至少,所以最好的方法是什麼? .NET是否有某種線程安全隊列系統,我可以使用它來確保結果得到正確處理並按順序處理?

+2

您使用的是什麼版本的.Net? .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可用,你也可以使用Parallel.ForEach作爲比上面提到的所有Task hocus-pocus更簡單的方法。

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

順便說一句,如果從Microsoft網站下載Reactive Extensions backport,實際上可以使用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會使這一過程更加簡單。 –