[英]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控制最大线程数,尽管我没有对此进行测试。
假设问题是; “如何限制工作线程的数量?” 答案是使用生产者-消费者队列,您可以在其中控制工作线程的数量。 只需将您的物品排队并让它处理工人。
这是您可以使用的通用实现。
你可以使用 ThreadPool.SetMaxThreads 方法
http://msdn.microsoft.com/en-us/library/system.threading.threadpool.setmaxthreads.aspx
在文档中,提到了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.