2011-05-16 103 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