2010-09-10 50 views
-1

我有一个包含项目集合的对象。我希望能够通过AddItem方法将项目添加到集合中,并且还要遍历集合中的所有项目。我的对象必须是线程安全的。我正在使用ReaderWriterLockSlim来确保正确的同步。 我应该如何同步GoThroughAllItems方法?我是否应该在整个持续时间(可能会很长)中启动一个大的ReadLock,或者是否应该释放从集合中获取的每个项目的锁定,然后再次获取下一个锁定的锁定?.NET中的同步读写集合

下面是一些示例代码:

 
private ReaderWriterLockSlim @lock = new ReaderWriterLockSlim(); 
private List items = new List(); 

public void AddItem(Item item) 
{ 
    [email protected](); 

    try 
    { 
     //do something with item and add it to the collection 
     this.items.Add(item); 
    } 
    finally 
    { 
     [email protected](); 
    } 
} 

public void GoThroughAllItems() 
{ 
    [email protected](); 

    try 
    { 
     foreach (Item item in this.Items) 
     { 
#if option2 
      [email protected](); 
#endif 

      //process item, which may take a long time 

#if option2 
      [email protected](); 
#endif 
     } 
    } 

#if option2 
    catch 
#endif 
#if option1 
    finally 
#endif 
    { 
     [email protected](); 
    } 
} 

回答

0

这里最好的方法是创建集合的副本,然后遍历它。它有很大的内存开销(但不久后会发布)。

伪代码:

read lock 
    foreach oldColl 
     populate newColl 
exit lock 

    foreach newColl 
     do things 

,你每个项目的锁代码将无法正常工作,因为其他线程可能会修改收集和它会导致错误,因为的foreach不允许集合的修改。

+0

谢谢,但是,一般来说,我认为副本可能太昂贵,不能考虑。 – 2010-09-10 15:43:00

+0

@Ricardo佩雷斯昂贵的条款是什么? – Andrey 2010-09-10 16:13:34

+0

当然,必须将N个元素从一侧复制到另一侧。 – 2010-09-11 08:35:55

0

因为在读取块中允许多个线程,所以我只是简单地选择foreach周围的读取区域的第一个选项,这并不重要,因为它很慢。另一方面,独占写操作非常快。所以这应该是一个很好的解决方案。