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