在.NET中同步读写集合

时间:2010-09-10 11:11:29

标签: .net synchronization locking readerwriterlockslim

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

以下是一些示例代码:

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

public void AddItem(Item item)
{
    this.@lock.EnterWriteLock();

    try
    {
        //do something with item and add it to the collection
        this.items.Add(item);
    }
    finally
    {
        this.@lock.ExitWriteLock();
    }
}

public void GoThroughAllItems()
{
    this.@lock.EnterReadLock();

    try
    {
        foreach (Item item in this.Items)
        {
#if option2
            this.@lock.ExitReadLock();
#endif

            //process item, which may take a long time

#if option2
            this.@lock.EnterReadLock();
#endif
        }
    }

#if option2
    catch
#endif
#if option1
    finally
#endif
    {
        this.@lock.ExitReadLock();
    }
}

2 个答案:

答案 0 :(得分:0)

这里最好的方法是创建一个集合副本,然后迭代它。它有很大的内存开销(但很快就会发布)。

伪代码:

read lock
   foreach oldColl
      populate newColl
exit lock

   foreach newColl
      do things

并且每个项目的锁定代码都不起作用,因为其他线程可能会修改集合并且会导致错误,因为foreach不允许修改集合。

答案 1 :(得分:0)

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