2009-09-20 63 views
3

我的目標是編寫一個程序,根據給定的用戶輸入來處理任意數量的任務。C#多線程 - 使用什麼方法?

假設在這種情況下任務的數量是1000。

現在,我想能夠產生一個動態數量的線程,並開始逐一處理任務。

我會假設我需要使用「同步」方法,而不是「異步」方法,以便萬一一個任務有問題時,我不希望它放慢其他任務的完成。

我會用什麼方法來完成上述操作?信號燈?線程池?我如何確保線程不會嘗試啓動已由另一個線程處理的任務? 「鎖」會處理這個問題嗎?

代碼示例和/或指向我的正確方向的網站鏈接將不勝感激。

編輯:與MSDN斐波那契示例的問題是,waitall方法最多隻能處理64個等待。由於1000個任務,我需要的不僅僅是這些。如何解決這種情況而不造成死鎖?

回答

10

這些任務是否獨立?如果是這樣的話,你基本上需要一個生產者/消費者隊列或一個自定義線程池,這對於同一事物來說是有效的不同視圖。您需要能夠將任務放入隊列中,並讓多個線程能夠從該隊列中讀取。

我在MiscUtil自定義線程池或有一個簡單的(非泛型由於年齡)生產者/消費者隊列在我threading tutorial(約一半時this page)。

如果這些任務合理長時間運行,我不會使用系統線程池 - 它會產生比你想要的更多的線程。如果您使用.NET 4.0 beta 1,則可以使用並行擴展。

我不太確定您對WaitAll的評論......您是否在試圖完成所有工作?在生產者/消費者隊列的情況下,這可能涉及在隊列中存在某種「停止」條目(例如消費線程理解爲「退出」的空引用),然後添加「WaitUntilEmpty」方法(應該相當容易實現)。請注意,您不需要等到最後的項目已經處理,因爲它們都是停止信號......在隊列清空的時候,所有真實的工作項目肯定都會被處理。

+0

他們是獨立的。 – Sev 2009-09-20 19:01:04

+0

我只是看着這個例子:http://msdn.microsoft.com/en-us/library/3dasc8as%28VS.80%29.aspx - 它使用一個WaitAll,並且該方法只能處理多達64 - - 在我的情況下,這是有問題的。使用WaitOne我讀取導致死鎖問題。但是你建議我不必等到他們全部完成之後(這對我來說是可能的) – Sev 2009-09-20 19:04:14

+0

@Sev:我說等待所有事情都要完成通常會比等待每個單獨的任務完成:) – 2009-09-20 19:16:06

2

您可能會想使用ThreadPool來管理它。

我推薦閱讀MSDN on How to use the ThreadPool in C#。它涵蓋了許多方面,包括射擊任務和簡單的同步。

Using Threading in C#是主要部分,並將涵蓋其他選項。

如果您碰巧在使用VS 2010測試版,並且面向.NET 4,那麼Task Parallel Library就是一個非常好的選擇 - 它簡化了一些這些模式。

+0

該示例的問題是waitall方法最多隻能處理64個等待。由於1000個任務,我需要的不僅僅是這些。 – Sev 2009-09-20 18:57:34

+0

您可以在循環中使用WaitOne,然後等待List或數組中的每個元素。 – 2009-09-20 18:59:06

+0

WaitOne不會導致死鎖問題? – Sev 2009-09-20 19:01:35

1

不能使用它(還),但新的任務類.NET 4將是理想的這種情況。
在此之前,ThreadPool是您最好的選擇。它具有(非常)有限的負載均衡形式。請注意,如果您嘗試啓動1000個線程,您可能會遇到Out of Memory異常。 ThreadPool將輕鬆處理。

如果您的同步問題可以容忍主線程中的Sleep(1)循環,則可以使用簡單的(互鎖)計數器處理您的同步問題。 ThreadPool缺少執行此操作的更方便的方法。

0

也許你可以使用BackgroundWorker類。它在線程池之上創建了一個很好的抽象。如果你想設置許多類似的工作,你甚至可以繼承它。

0

如前所述,.NET 4具有優秀的任務並行庫。但是你可以在.NET 3.5中使用它的June 2008 CTP。我自己一直在爲一些業餘愛好項目做這個,但如果這是一個商業項目,你應該檢查是否有法律問題。