我有一个网格,其定义为:List>
,其中“Cell”是我的自定义类。
我的程序有几个线程,它们访问网格上的各种坐标,并更改“Cell”类中的数据。但我一次只希望一个线程将数据写入“Cell”对象。
我认为使用并发集合(例如 ConcurrentBag)会很有用,但似乎所有并发集合都只有添加项目或从集合中删除它们的方法。似乎没有线程安全的方法来更改此类集合中保存的数据。
我在这里遗漏了一些东西,还是没有“简单的方法”来使用这样的集合来做到这一点?
I have a grid which is defined as: List<List<Cell>>
, where "Cell" is a custom class of mine.
My program has several threads which access various coordinates on the grid, and change data in the "Cell" class. But I only want one thread writing data to a "Cell" object at a time.
I thought using concurrent collections such as ConcurrentBag would be of service, but it seems that all the Concurrent Collections only have methods to ADD items or REMOVE them from the collection. There doesn't seem to be a thread-safe way to CHANGE data held within such a collection.
Am I missing something here, or is there no "easy way" to do it using such collections?
发布评论
评论(3)
您可以简单地使用互斥体来对单元格内容进行线程安全访问。它的工作原理如下:
请参阅 http://msdn.microsoft .com/en-us/library/system.threading.mutex.aspx 了解更多详细信息。
You can simply use mutexes for thread-safe access to your cell contents. It works something like this:
See http://msdn.microsoft.com/en-us/library/system.threading.mutex.aspx for more details.
你读过这篇论文吗?
.NET Framework 4 中的线程安全集合及其性能特征
使用
ConcurrentBag
的示例代码:您还可以看看ConcurrentDictionary 对添加和更新的支持。
Have you read this paper?
Thread-safe Collections in .NET Framework 4 and Their Performance Characteristics
Sample code using
ConcurrentBag
:You can also take a look at ConcurrentDictionary’s support for adding and updating.
并发集合的目的是作为一种安全修改集合本身的方法;不是项目。您必须将自己的同步原语添加到
Cell
类中。如果外部和内部List
实例本身保持不变,则无需对它们应用同步。您提到您将有很多读者,但只有一位作者。这是一个非常重要的细节。这意味着任何无锁同步策略都变得更加容易实现。然而,我不鼓励走这条路,因为它仍然很难走对路。但是,这也可能意味着
ReaderWriterLockSlim
可能比锁
性能更好。您必须对两者进行试验,看看哪一种能够提供可维护性和效率的最佳平衡。我的预感是,尽管有多个读取器和一个写入器,但传统的
锁
会执行得更快,但它值得测试。当输入代码时,手指确实要容易得多。这是两者的示例代码。
和
The concurrent collections were intended as a means of safely modifying the collection itself; not the items. You will have to add your own synchronization primitives to the
Cell
class. If the outer and innerList
instances themselves will remain unchanged there is no need to apply synchronization to them.You mentioned that you will have many readers, but only one writer. That is an incredibly important detail. It means that any lock-free synchronization strategies become dramatically easier to implement. However, I do not encourage going down that route as it would still be quite difficult to get right. But, it could also mean that the
ReaderWriterLockSlim
might perform better than alock
.You will have to experiment with both to see which one provides the best balance of maintainability and efficiency. My hunch is that you will find a traditional
lock
will perform faster despite having multiple readers and a single writer, but it is worth testing. It is certainly a lot easier on the fingers when typing out the code.Here is sample code for both.
and