c#中的线程具有有限数量的作业和有限数量的活动线程
本文关键字:线程 活动 作业 | 更新日期: 2023-09-27 18:06:42
我有一个循环,看起来像这样:
var list = new List<float>();
while (list.Count < wantedNumberOfJobs)
{
var resource = ... //gets the resource
lock (resource)
{
ThreadPool.QueueUserWorkItem(DoWork, /*wrap resource and list into an object*/);
}
}
//continue pass this point when all the threads are finished
和工作方法:
private void DoWork(object state)
{
var list = (/*wrapperObject*/)state.List;
var someFloat = //do the work to get the number
lock (list)
{
list.Add(someFloat);
}
}
本质上,我想做一个大的,但一个特定的(由wantedNumberOfJobs
给定)完成的工作数。这些作业中的每一个都将单个项目插入list
,正如您在DoWork
方法中看到的那样。
我不确定这段代码是否向我保证list
将包含超过指定点的wantedNumberOfJobs
项。我还想限制活动线程的数量。我已经使用了System.Threading.Semaphore
类,但我不确定这是最好的解决方案。
我很感激任何帮助。谢谢!
也许你可以使用Parallel。For,例如:
Parallel.For(0, wantedNumberOfJobs, i => {
var resource = ... //gets the resource
DoWork(Resource);
});
你真的应该得到一本《并行编程模式:在。net框架中理解和应用并行模式》。
它解释了在。net 4中谁应该使用并行扩展,以及如何影响并发运行的作业数量。对于您的列表,您还应该查看Concurrent命名空间,以找到一个线程安全的替代方案。
既然你标记了这个c# 4,考虑使用TaskPool中的任务而不是TreadPool中的线程。这将根据您拥有的处理器数量限制您使用的线程数量。另外,考虑删除一些锁,因为每个锁都需要上下文切换和进程锁定,这首先会有效地限制甚至消除使用多线程的优势。
你可能会在list
中找到比wantedNumberOfJobs
更多的项目。这是因为while循环正在根据列表的当前内容决定是否对新工作项进行排队。根据DoWork
花费的时间长短,在将任何项添加到list
之前,它可能会将数百或数千项排队。
解决这个问题的一种方法是让while循环跟踪它排队的工作项的数量,并在到达wantedNumberOfJobs
时停止。
PLINQ是否足够?http://msdn.microsoft.com/en-us/library/dd460714.aspx