2013-01-17 26 views
3

我有一个Dictionary<object1, List<object2>(我为我的结构,这是一个更复杂一点的抽象化)。确保线程安全操作的字典中的值的列表

字典内的列表在非并行上下文中初始化,但向列表中添加新元素需要线程安全方法。删除项目不会发生(字典对象将在事务结束时处理)。 此外,键值对仅在初始化时添加,因此在工作期间不会从字典中添加或删除任何键,只更新值。

我不能使用concurent集合,我被困在旧的.NET Framework中。

起初,我用ReadWriteSlimlock锁定了整本字典。那么,这是非常糟糕的表现明智的。有很多添加操作发生,他们只是等待另一个。只锁定每个列表是一个更好的解决方案,因为至少我为每个密钥并行执行了一些操作。 另外,添加操作不是简单的list.Add(object2),其他一些复杂操作需要在添加线程安全区域时发生。

但我不知道是什么来实现它的最好办法:

  1. lock(dictionary.Value)
  2. 使用ReadWriteSlimlock的字典(每个键一个)?
  3. 还有其他更好的解决方案吗?

回答

2

另一种解决方案可能是实施您的同类List<object>类。 喜欢的东西:

public class ConcurentList { 
    private object sync = new object(); 
    private List<object> realList = new List<object>(); 


    public void Add(object o) { 
     lock(sync){ 
      realList.Add(o); 
     } 
    } 

    /** ADD OTHERE METHODS IMPEMENTATION IF NEED **/ 

} 

,并在字典有:

Dictionary<object1, ConcurentList> 

为什么封装和,而不是延长List<object>,是造成Add方法不是虚拟的,所以唯一的办法,你可以“覆盖”它正在使用new关键字,这是保证被称为只有如果使用完全相同的类型,这意味着如果您将列表投给b因为它不会被调用,所以孔结构将失败。

通过封装,你只给调用者一个方法,在哪里控制一切。

不知道这个解决方案是否符合您的需求,但希望它能告诉您如何管理的东西。

+0

由于添加是我的实际问题,我真的很喜欢封装ideea。谢谢你的提示! –

1

为什么不写你自己的并发线程安全变体Dictionary<>List<>?这是我为.NET 2所做的。

我个人选择了ReaderWriterLockSlim,因为它允许您根据访问模式控制锁定,而且大多数情况下我的列表正从更多被读取的内容中读取。

但是,您正在进行大量添加,因此您可能想要同时尝试这两种方法(lockReaderWriterLockSlim),并查看哪个性能更好。

+0

在某些情况下,'ReaderWriterLockSlim'在这种情况下似乎很奇怪(我写的是并行的,最后只写了一次)。我认为'ReaderWriterLockSlim'适用于涉及更多阅读的情况。最后,我想我会实施一些比较他们的想法,因为在这个问题中,绩效是一个很大的问题。 –

+0

是的,据我了解,它主要针对有读/写需求的地方,并且存在很多读竞争。 – Lloyd

1

如果从列表中读取与书写同时发生,则为每个字典条目构造一个ReaderWriterLockSlim对象将是一个最佳解决方案,因为多个阅读器可以同时在同一列表上进行处理。这只比使用lock(key)稍微难一些,并且在少数列表比其他列表更频繁地被读取的情况下,它具有提高性能的潜力。

如果你去ReaderWriterLockSlim路线,这是一个好主意,包装清单,并在一个类中的锁,而不是创建一个单独的字典只为读写器锁:

class LockableList { 
    public ReaderWriterLockSlim RwLock {get;private set;} 
    public List<object2> Data {get;private set;} 
    public LockableList() { 
     RwLock = new ReaderWriterLockSlim(); 
     Data = new List<object2>(); 
    } 
} 
... 
Dictionary<object1,LockableList> myDictionary; 

结合列表和外观将让你查找一次字典条目,锁定它的阅读或适当的写作,并与相关列表进行工作。

+0

你的想法包装列表和锁定是伟大的!值得考虑的不仅在这种情况下。 –