2011-05-16 102 views
3

我在我的應用程序中使用了ThreadPool。我已經先通過以下設置線程池的限制:限制線程池線程的數量

ThreadPool.SetMaxThreads(m_iThreadPoolLimit,m_iThreadPoolLimit); 
m_Events = new ManualResetEvent(false); 

,然後我一直在使用以下

WaitCallback objWcb = new WaitCallback(abc); 
ThreadPool.QueueUserWorkItem(objWcb, m_objThreadData); 

這裏ABC是函數名排隊的作業,我我在打電話。 在此之後,我做以下,使我的所有線程來1點和主線程接管並繼續進一步

m_Events.WaitOne(); 

我的線程限制爲3,我面臨的問題是,對inspite線程池限制設置爲3,我的應用程序同時處理超過3個文件,而它應該一次只處理3個文件。請幫我解決這個問題。

+1

你應該檢查SetMaxThreads()的返回值。 – Simone 2011-05-16 13:15:01

+4

除非您知道自己在做什麼,否則最好不要混淆ThreadPool中的線程數。讓運行時處理它。如果您需要限制同時訪問的文件數量,請使用更好的方法 - 比如使用信號量。 – 2011-05-16 13:18:48

+0

Microsoft不允許您設置最大線程 Kostadin 2014-08-15 07:57:38

回答

5

你在用什麼樣的電腦?

MSDN

你不能設置工人 線程的數目或I/O 完成線程來比 計算機處理器的數目的數目較小 數量。

如果你有4個核心,那麼你可以有最小的是4

還要注意:

如果公共語言運行時 託管,例如通過互聯網 信息服務(IIS)或SQL服務器,主機可以限制或防止對線程池大小的更改(更改爲 )。

如果這是IIS託管的網站,則無法更改線程池大小。

+0

是的,我已經嘗試將設置最大線程的1個參數設置爲0,仍然無法正常工作。 – 2011-05-16 13:17:16

+1

@Sanchaita無法將工作線程數設置爲0.您必須將其設置爲大於計算機處理器數的數字(每個人至少有1個)。如果你有一個四核,那麼你需要將它設置爲至少4.在我的I7上,Windows 7認爲我有8個內核。該數字必須至少爲8. – 2011-05-16 13:20:50

0

你說這些文件已經打開:它們實際上是被主動處理還是隻是保持打開? 如果你讓他們打開:那裏,做到了!依靠連接和資源(這是一個數據庫連接在我的情況下)關閉在範圍結束應該工作,但它可以採取處置/垃圾回收踢in。

1

您應該使用信號量對象來限制concurent線程。

3

一個更好的解決方案涉及使用可以限制併發訪問資源的Semaphore 。在你的情況下,資源只是一個處理工作項目的代碼塊。

var finished = new CountdownEvent(1); // Used to wait for the completion of all work items. 
var throttle = new Semaphore(3, 3); // Used to throttle the processing of work items. 
foreach (WorkItem item in workitems) 
{ 
    finished.AddCount(); 
    WorkItem capture = item; // Needed to safely capture the loop variable. 
    ThreadPool.QueueUserWorkItem(
    (state) => 
    { 
     throttle.WaitOne(); 
     try 
     { 
     ProcessWorkItem(capture); 
     } 
     finally 
     { 
     throttle.Release(); 
     finished.Signal(); 
     } 
    }, null); 
} 
finished.Signal(); 
finished.Wait(); 

在上面WorkItem的代碼是一個假設性的類,封裝處理您的任務所需的具體參數。

Task Parallel Library使這種模式更容易。只需使用Parallel.ForEach方法並指定一個ParallelOptions.MaxDegreesOfParallelism即可限制併發性。

var options = new ParallelOptions(); 
options.MaxDegreeOfParallelism = 3; 
Parallel.ForEach(workitems, options, 
    (item) => 
    { 
    ProcessWorkItem(item); 
    }); 

我應該指出的是,我不喜歡阻斷使用Semaphore或任何阻擋裝置ThreadPool線程。它基本上浪費了線程。你可能想要完全重新考慮你的設計。

+0

對於ParallelOptions – Learner 2014-08-14 21:14:50