【问题标题】:.Net 4.0 Parallel Programming - how to write data to concurrent collections?.Net 4.0 并行编程 - 如何将数据写入并发集合?
【发布时间】:2010-09-17 18:25:16
【问题描述】:
我有一个网格,定义为:List<List<Cell>>,其中“Cell”是我的自定义类。
我的程序有几个线程可以访问网格上的各种坐标,并更改“Cell”类中的数据。但我只希望一个线程一次将数据写入“Cell”对象。
我认为使用 ConcurrentBag 等并发集合会有所帮助,但似乎所有并发集合都只有添加项目或从集合中删除项目的方法。似乎没有一种线程安全的方式来更改此类集合中保存的数据。
我在这里遗漏了什么,还是没有“简单的方法”来使用这样的集合?
【问题讨论】:
标签:
c#
.net-4.0
parallel-processing
concurrent-programming
concurrent-collections
【解决方案3】:
并发集合旨在作为一种安全修改集合本身的手段;不是项目。您必须将自己的同步原语添加到Cell 类。如果外部和内部List 实例本身保持不变,则无需对它们应用同步。
你提到你会有很多读者,但只有一个作者。这是一个非常重要的细节。这意味着任何无锁同步策略都变得非常容易实现。但是,我不鼓励沿着这条路线走,因为它仍然很难做到正确。但是,这也可能意味着ReaderWriterLockSlim可能比lock表现更好。
您必须对这两种方法都进行试验,看看哪一种能在可维护性和效率之间取得最佳平衡。我的预感是你会发现传统的lock 尽管有多个阅读器和一个编写器,但它的性能会更快,但它值得测试。输入代码时,手指肯定会轻松很多。
这是两者的示例代码。
public class Cell
{
private object m_LockObject = new object();
public object ReadMyState()
{
lock (m_LockObject)
{
// Return the data here.
}
}
public void ChangeMyState()
{
lock (m_LockObject)
{
// Make your changes here.
}
}
}
和
public class Cell
{
private ReaderWriterLockSlim m_LockObject = new ReaderWriterLockSlim();
public object ReadMyState()
{
m_LockObject.EnterReadLock();
try
{
// Return the data here.
}
finally
{
m_LockObject.ExitReadLock();
}
}
public void ChangeMyState()
{
m_LockObject.EnterWriteLock();
try
{
// Make your changes here.
}
finally
{
m_LockObject.ExitWriteLock();
}
}
}