我对控制我想要运行的并发线程数有疑问。让我解释一下我目前的做法:例如
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;
这是我目前采用的路径。但是我根本不喜欢它。我知道我可以“管理”线程池本身,但我听说不建议这样做。那么替代方案是什么?信号量类?
感谢。
答案 0 :(得分:4)
您可以考虑使用TPL或PLINQ,而不是直接使用ThreadPool
。例如,使用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仅在可以提高性能的情况下实现添加更多处理线程的算法。
答案 1 :(得分:3)
不要使用THE treadpool,另外一个(只需查看谷歌,有六个实现)并自行管理。
管理the treadpool是不可取的,因为很多内部工作可能会进行,管理你的OWN线程池实例是完全可以的。
答案 2 :(得分:1)
看起来您可以使用ThreadPool.SetMaxThreads控制最大线程数,但我还没有测试过。
答案 3 :(得分:1)
假设问题是; “我如何限制工作线程的数量?”答案是使用生产者 - 消费者队列,您可以在其中控制工作线程的数量。只需排队您的物品并让它处理工人。
Here是您可以使用的通用实现。
答案 4 :(得分:0)
您可以使用ThreadPool.SetMaxThreads方法
http://msdn.microsoft.com/en-us/library/system.threading.threadpool.setmaxthreads.aspx
答案 5 :(得分:0)
在documentation中,提到SetMaxThreads
...
public static bool SetMaxThreads (
int workerThreads,
int completionPortThreads
)
设置可以同时处于活动状态的线程池的请求数。高于该数字的所有请求将保持排队,直到线程池线程可用。
然而:
您不能将工作线程数或I / O完成线程数设置为小于计算机中处理器数的数字。
但我想通过使用非单例线程池可以更好地服务。
答案 6 :(得分:0)
没有理由处理混合线程同步构造(例如AutoResetEvent)和ThreadPool。
您可以使用一个可以作为协调器的类,负责异步执行所有代码。
使用任务或APM模式包裹“Item_Thread”执行的操作。然后使用Jeffrey Richter的 AsyncCoordinator 类(可以在CLR书中通过C#第3版的代码中找到)。