繁体   English   中英

C# 多线程 - 限制并发线程的数量

[英]C# Multi-Threading - Limiting the amount of concurrent threads

我对控制我想要运行的并发线程的数量有疑问。 让我解释一下我目前所做的:例如

 var myItems = getItems(); // is just some generic list

 // cycle through the mails, picking 10 at a time
 int index = 0;
 int itemsToTake = myItems.Count >= 10 ? 10 : myItems.Count;
 while (index < myItems.Count)
 {
     var itemRange = myItems.GetRange(index, itemsToTake);
     AutoResetEvent[] handles = new AutoResetEvent[itemsToTake];

     for (int i = 0; i < itemRange.Count; i++)
     {
         var item = itemRange[i];
         handles[i] = new AutoResetEvent(false);

         // set up the thread
         ThreadPool.QueueUserWorkItem(processItems, new Item_Thread(handles[i], item));
     }

    // wait for all the threads to finish
    WaitHandle.WaitAll(handles);

    // update the index
    index += itemsToTake;
    // make sure that the next batch of items to get is within range
    itemsToTake = (itemsToTake + index < myItems.Count) ? itemsToTake : myItems.Count -index;

这是我目前走的一条路。 但是我一点也不喜欢。 我知道我可以“管理”线程池本身,但我听说这样做是不可取的。 那么替代方案是什么? 信号量 class?

谢谢。

除了直接使用ThreadPool ,您还可以考虑使用 TPL 或 PLINQ。 例如,使用 PLINQ,您可以执行以下操作:

getItems().AsParallel()
          .WithDegreeOfParallelism(numberOfThreadsYouWant)
          .ForAll(item => process(item));

或使用Parallel

var options = new ParallelOptions {MaxDegreeOfParallelism = numberOfThreadsYouWant};
Parallel.ForEach(getItems, options, item => process(item));

确保指定并行度确实可以提高应用程序的性能。 TPL 和 PLINQ 默认使用 ThreadPool,它在管理正在运行的线程数量方面做得非常好。 在 .NET 4 中,ThreadPool 实现了仅在提高性能时才添加更多处理线程的算法。

不要使用跑步机,再买一个(只需寻找谷歌,有六种实现方式)并自己管理。

管理线程池是不可取的,因为很多内部工作可能 go 那里,管理你自己的线程池实例是完全可以的。

看起来您可以使用ThreadPool.SetMaxThreads控制最大线程数,尽管我没有对此进行测试。

假设问题是; “如何限制工作线程的数量?” 答案是使用生产者-消费者队列,您可以在其中控制工作线程的数量。 只需将您的物品排队并让它处理工人。

是您可以使用的通用实现。

文档中,提到了SetMaxThreads ...

public static bool SetMaxThreads (
int workerThreads,
int completionPortThreads
)

设置可以并发活动的线程池的请求数。 在线程池线程可用之前,所有高于该数量的请求都会排队。

然而:

您不能将工作线程数或 I/O 完成线程数设置为小于计算机中处理器数的数字。

但是我想无论如何,使用非单例线程池会更好地为您服务。

没有理由处理混合线程同步结构(例如 AutoResetEvent)和 ThreadPool。

您可以使用 class 作为协调器,负责异步执行所有代码。

使用任务或 APM 模式包装“Item_Thread”所做的事情。 然后使用 Jeffrey Richter 的AsyncCoordinator class(可以在 CLR 中通过 C# 第 3 版的代码中找到)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM