Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/wix/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#中的线程,作业数量有限,活动线程数量有限_C#_Multithreading_C# 4.0 - Fatal编程技术网

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);
            });