Threadpool QueueUserWorkItem不使用SetMaxThreads,GetMaxThreads

时间:2012-05-19 13:55:59

标签: c# multithreading .net-2.0 threadpool

我正在使用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上运行。

3 个答案:

答案 0 :(得分:2)

您必须设置最小线程数。

一般来说,这不是一个好主意,运行更多的线程比处理器内核更多更少完成工作,因为操作系统花费时间交换进出。这些上下文切换并不便宜。线程池管理器尽力将活动线程数限制为核心数。只允许更多线程在现有线程未及时完成时运行。最大线程数。默认值很大,在你的情况下为1000。

仅当这些工作线程执行的工作量不足时才增加min线程,因为它们在I / O上经常被阻塞。在这种情况下,你真的应该考虑Thread对象而不是线程池线程。

答案 1 :(得分:0)

假设这是一个C#应用程序,您可以使用.NET Framework 4的并行编程模型并将线程限制为20个。

Parallel.For(0, n, new ParallelOptions { MaxDegreeOfParallelism = 20 }, 
  i => 
  { 
    DoWork(i);
  }); 

但是,如果这是一个网站/应用程序,最好远离ThreadPool,除了非常小的作业,1-2个线程,因为你不想饿死ThreadPool。并且永远不要在代码中设置最大或最小线程,因为它会影响整个站点,以及使用相同线程池的所有其他站点。

在这种情况下,我建议改为使用SmartThreadPool

答案 2 :(得分:0)

SetMinThreads课程中还有ThreadPool。将min和max设置为相同的值“应该”修复线程的数量,但实际发生的事情是任何人的猜测。

MSDN

  

线程池提供新的工作线程或I / O完成线程   按要求,直到达到每个类别的最低值。

因此,将最小线程数设置为20应该会在池中为您提供不少于20个线程。