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类,但我不确定这是最好的解决方案。

我很感激任何帮助。谢谢!

c#中的线程具有有限数量的作业和有限数量的活动线程

也许你可以使用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