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上运行。

Threadpool QueueUserWorkItem without using SetMaxThreads,Get

您必须设置最小线程数。

一般来说,这不是一个好主意,运行比处理器内核更多的线程通常会完成更少的工作,因为操作系统会花时间将它们换入和换出。 这些上下文切换并不便宜。 线程池管理器会尽力将活动线程数限制为内核数。 仅当现有线程未及时完成时,才允许运行更多线程。 最多达到最大线程数。 默认情况下是一个巨大的值,在您的情况下为 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。