C#中的线程,作业数量有限,活动线程数量有限
我有一个类似这样的循环:C#中的线程,作业数量有限,活动线程数量有限,c#,multithreading,c#-4.0,C#,Multithreading,C# 4.0,我有一个类似这样的循环: 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 objec
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
基本上,我想做一个大的,但具体的(由wantedNumberOfJobs
给出)完成的工作数量。正如您在DoWork
方法中所看到的那样,每个作业都会将单个项目插入到列表中
我不确定此代码是否向我保证list
将包含wantedNumberOfJobs
项超过指定点。我还想限制活动线程的数量。我使用了System.Threading.Semaphore
类,但不确定这是最佳解决方案
我非常感谢你的帮助。谢谢 在列表
中,您可能会得到比想要的工作数量
更多的项目。这是因为while循环根据列表的当前内容决定是否将新工作项排队。根据DoWork
所需的时间,它可以将数百或数千个项目排队,然后再将任何项目添加到列表中
解决这个问题的一种方法是让while循环跟踪它所排队的工作项的数量,并且当它到达“代码> WordTeNeBoObWorks<代码> >时停止。
< P>自从您标记了这个C 4,考虑使用任务池中的任务而不是来自Trand池的线程。这将根据您拥有的处理器数量限制您使用的线程数量。此外,考虑删除一些锁,因为每个锁都需要上下文切换和进程锁定,从而有效地限制或甚至消除了首先使用多线程的优势。 PLIQ对您来说可能足够了吗?p> 也许您可以使用Parallel。例如:
Parallel.For(0, wantedNumberOfJobs, i => {
var resource = ... //gets the resource
DoWork(Resource);
});
你真的应该得到一份
它解释了谁使用.NET4中的并行扩展,以及如何影响并发运行的作业数量。对于您的列表,您还应该查看以找到线程安全的替代方案。就是这样。朴素典雅。谢谢。这篇文章是一个很好的线程资源。谢谢我也在其中找到了相似之处。因为这是Steven建议的,也是我要做的。此外,我还研究了并发名称空间和BlockingCollection的描述,因为我正在为每个DoWork(…)作业向列表中添加一个元素。我只是想知道我是否需要在添加时锁定BlockingCollection,还是“线程安全”涵盖了这一点?@gligoran:你不需要锁。只需使用Add()
,CompleteAdding()
,getConsumineumerable()
和/或,Take()
。但是不应该需要站点上的锁,因为并发集合在内部就是这样做的。只需确保您熟悉生产者/消费者模式(文档中描述)即可正确使用该集合。
Parallel.For(0, wantedNumberOfJobs, i => {
var resource = ... //gets the resource
DoWork(Resource);
});