限制线程池线程的数量

我在我的应用程序中使用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.我遇到的问题是,尽管线程池限制设置为3,我的应用程序同时处理3个以上的文件,而它一次只能处理3个文件。 请帮我解决这个问题。

你用的是什么类型的电脑?

来自MSDN

您不能将工作线程数或I / O完成线程数设置为小于计算机中处理器数的数字。

如果你有4个核心,那么你可以拥有的最小核心是4个核心。

另请注意:

如果托管公共语言运行库(例如,通过Internet信息服务(IIS)或SQL Server),则主机可以限制或阻止更改线程池大小。

如果这是由IIS托管的网站,则您也无法更改线程池大小。

更好的解决方案是使用Semaphore ,它可以限制对资源1的并发访问。 在您的情况下,资源只是一个处理工作项的代码块。

 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是一个假设的类,它封装了处理任务所需的特定参数。

任务并行库使这种模式更容易。 只需使用Parallel.ForEach方法并指定一个限制并发性的ParallelOptions.MaxDegreesOfParallelism

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

1我应该指出,我不喜欢使用Semaphore或任何阻塞设备阻止ThreadPool线程。 它基本上浪费了线程。 您可能想要完全重新考虑您的设计。

您应该使用Semaphore对象来限制concurent线程。

你说文件是开放的:它们实际上是在积极处理,还是只是保持开放状态? 如果你要把它们打开:在那里,做到了! 依赖于连接和资源(在我的情况下是一个数据库连接)在范围结束时关闭应该可以工作,但是可以采取配置/垃圾收集来启动。