Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/302.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_Concurrency - Fatal编程技术网

C# 多个作者,一个读者,哪个收藏

C# 多个作者,一个读者,哪个收藏,c#,multithreading,concurrency,C#,Multithreading,Concurrency,我的情况是: 多个线程必须同时写入同一集合(add和addrange)。物品的顺序不是问题。 当所有线程都完成(连接)并返回主线程时,我需要以foreach样式快速读取所有收集的数据,因为所有线程都完成了,所以不需要实际锁定 在“旧时代”,我可能会在列表中使用readerwriter锁,但对于新的并发集合,我想知道是否有更好的替代方法。我只是不知道是哪一个,因为大多数并发集合似乎都假设读者也在并发线程上。试试这个 根据集合的描述: 表示线程安全的无序对象集合 我相信这符合您处理多个线程的标准,并

我的情况是:

多个线程必须同时写入同一集合(add和addrange)。物品的顺序不是问题。 当所有线程都完成(连接)并返回主线程时,我需要以foreach样式快速读取所有收集的数据,因为所有线程都完成了,所以不需要实际锁定

在“旧时代”,我可能会在列表中使用readerwriter锁,但对于新的并发集合,我想知道是否有更好的替代方法。我只是不知道是哪一个,因为大多数并发集合似乎都假设读者也在并发线程上。

试试这个

根据集合的描述:

表示线程安全的无序对象集合


我相信这符合您处理多个线程的标准,并且项目的顺序并不重要,稍后当您回到主线程时,您可以快速地对集合进行foreach迭代并对每个项目执行操作

我认为您不想使用
System.collections.Concurrent
中的任何集合。它们通常有额外的开销以允许并发读取

除非有很多争用,否则最好锁定一个简单的
列表
,然后添加到其中。随着列表大小的调整,您将有少量开销,但这种情况非常少见

但是,在这种情况下,我可能只需要为每个线程添加
列表,而不是共享的,然后在处理结束时合并它们,或者简单地迭代每个集合中的所有元素

您可以使用
ConcurrentBag
,然后在准备读取时调用
.ToArray()
GetEnumerator()
(绕过每次读取的惩罚),但您可能会发现插入的速度比在简单的
列表上手动写入锁定的速度慢一点。这实际上取决于争用的数量。
ConcurrentBag
非常适合分区,但正如您所指出的,它适合并发读写

一如既往,对您的特定情况进行基准测试!多线程性能在很大程度上取决于实际使用中的许多因素,数据类型、插入次数等因素都会极大地改变结果——一点现实值一加仑理论

物品的顺序不是问题。当所有线程都完成(加入)并且im回到主线程时,我需要读取所有收集的数据

您根本没有声明线程安全集合的要求。共享一个收藏是没有意义的,因为你从来不会在写的同时阅读。所有的写作都发生在同一个集合上也不重要,因为顺序并不重要。这也不重要,因为顺序无论如何都是随机的


因此,只需给每个线程分配自己的集合即可,无需锁定。然后逐个迭代,无需锁定。

如果您使用的是.Net 4.0或更高版本。ConcurrentBag应该能解决你的问题。如果你不关心元素的顺序和移除,我认为这是最好的。我已经看过了,但是concurrentbag上的foreach不是意味着每次读取都会有锁惩罚吗?让旧的读写器锁更有效?@汉斯和菲利普·里克,你说得绝对正确。这里根本没有理由使用并发集合。现在对我来说,这是显而易见的,我被一个事实蒙蔽了双眼,而且多疑,那就是我必须编很多线索。Thx用于清除:)。我已经看过了,但是concurrentbag上的foreach是否意味着每次读取都会受到锁惩罚?使旧的readerwriter锁更高效?@ChristianMikkelsen您运行的是.NET4.0还是.NET4.5?下面的博客文章讨论了
ConcurrentBag
性能:@ChristianMikkelsen不,你应该很好:ConcurrentBag.GetEnumerator()此时返回快照,因此不会锁定集合。有关基准测试的建议,请参见:+1。Philip是对的,您确实想知道实际数据/读/写的行为。