控制c#中同步线程数的最佳方法

时间:2010-11-24 10:34:51

标签: c# multithreading

我有一个简单的多线程程序,具有以下结构。

public void someFunction()
{

    List<object> objList = new List<object>();
    //objList populated here

    foreach(object o in objList)
    {
        Thread aThread = new Thread (new ParameterizedThreadStart(doSomething));
        aThread.Start(o);
    }
}

static void doSomething(object o)
{
    //Do something with o.
}

这很好用,但我遇到了限制同时运行theads数量的问题。比如我想定义int maxThreads = 25。我能想到的最佳方式就是:

SomeThreadsafeCounter c = new SomeThreadsafeCounter();

foreach(object o in objList)
{
    while (c < 26){ wait; }
    c++;
    Thread aThread = new Thread (new ParameterizedThreadStart(doSomething));
    aThread.Start(o);
    c--;
}

我确定这不是正确的方法,有更好的方法吗?

5 个答案:

答案 0 :(得分:1)

Semaphores是执行此操作的常用技巧。

答案 1 :(得分:1)

为什么不使用内置的东西,如:

  1. 线程池(ThreadPool.QueueUserWorkItem
  2. 任务 - 并行库
  3. 并行LINQ
  4. Parallel.ForEach
  5. 示例:

    Parallel.ForEach(objList,doSomething);
    

答案 2 :(得分:1)

如果使用.net 2.0或更高版本,则可以使用信号量。

信号量将允许您定义threds的最大限制,以及何时可以释放信号量对象以在线程数大于信号量对象中​​的指定限制时输入等待线程。

答案 3 :(得分:1)

您可以使用.net 4中包含的任务并行库执行此操作。

ParallelOptions options = new ParallelOptions();
options.MaxDegreeOfParallelism = 25;

Parallel.ForEach(objList, options, item => doSomething(item));

Parallel.ForEach有很多重载,我不确定我是否有正确的重载。

此处有更多信息:http://msdn.microsoft.com/en-us/library/dd537608.aspx

答案 4 :(得分:1)

如果您在4.0之前使用.net,那么您应该编写一个多线程生产者消费者队列。在构造函数中,您可以指定工作线程限制。这样做的好处是,您可以将工作线程创建和线程同步与实际功能代码分开。 Web和StackOverflow上有很多例子。

如果您使用的是.net 4.0;显然,您可以查看System.Collections.Concurrent类型和前面提到的并行类型。