Threadpool QueueUserWorkItem without using SetMaxThreads,Get
本文关键字:Get SetMaxThreads using QueueUserWorkItem without Threadpool | 更新日期: 2023-09-27 18:34:37
我正在使用Threadpool在c# .NET 2.0中进行一些并行处理。
法典:
int MAXThreads=GetConfigValue("MaxThreadLimit"); //This value is read from app.config
ManualResetEvent[] doneEvents=new ManualResetEvent[MAXThreads];
for(int i=0;i<MaxThreads,i++)
{
doneEvents[i]=new ManualResetEvent(false);
//create workload
DoProcess job=new DoProcess(workload,doneEvents[i]);
ThreadPool.QueueUserWorkItem(job.ThreadPoolCallBack,i);
}
WaitHandle.WaitAll(doneEvents);
//proceed
Class DoProcess
{
private WorkLoad load;
private ManualResetEvent doneEvent;
public DoProcess(WorkLoad load,ManualResetEvent doneEvent)
{
this.load=load;
this.doneEvent=doneEvent;
}
public void ThreadPoolCallBack(object index)
{
//Do Processing
doneEvent.Set();
}
}
正在从配置中读取 MAXThreads 值,但我想这与生成的实际线程数无关。只有少数 ~4-5 个线程处理所有工作负载。我希望线程数固定在 20 左右。我怎样才能做到这一点?我错过了什么吗?..SetMaxThreads 是否解决了这个问题?..上面的代码将在四核CPU上运行。
您必须设置最小线程数。
一般来说,这不是一个好主意,运行比处理器内核更多的线程通常会完成更少的工作,因为操作系统会花时间将它们换入和换出。 这些上下文切换并不便宜。 线程池管理器会尽力将活动线程数限制为内核数。 仅当现有线程未及时完成时,才允许运行更多线程。 最多达到最大线程数。 默认情况下是一个巨大的值,在您的情况下为 1000。
仅当这些工作线程由于在 I/O 上被频繁阻塞而未执行足够的工作时,才增加最小线程数。 在这种情况下,您确实应该考虑 Thread 对象而不是线程池线程。
ThreadPool
类中也有SetMinThreads
。 将最小值和最大值设置为相同的值"应该"可以修复线程数,但幕后实际发生的事情是任何人的猜测。
MSDN:
线程池提供新的工作线程或 I/O 完成线程 按需,直到达到每个类别的最小值。
因此,将最小线程数设置为 20 应该在池中提供不少于20个线程。
假设这是一个 C# 应用程序,则可以使用 .NET Framework 4 的并行编程模型并将线程限制为 20 个。
Parallel.For(0, n, new ParallelOptions { MaxDegreeOfParallelism = 20 },
i =>
{
DoWork(i);
});
但是,如果这是一个网站/应用程序,最好远离 ThreadPool,除了非常小的工作,1-2 个线程,因为你不想饿死 ThreadPool。 并且永远不要在代码中设置最大或最小线程数,因为这会影响您的整个站点以及使用同一线程池的所有其他站点。
在这种情况下,我建议改用SmartThreadPool。