-1

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

这是一些示例代码:

私有 ReaderWriterLockSlim @lock = new ReaderWriterLockSlim();
私有列表项 = 新列表();

公共无效添加项(项目项)
{
    this.@lock.EnterWriteLock();

    尝试
    {
        //对项目做一些事情并将其添加到集合中
        this.items.Add(item);
    }
    最后
    {
        this.@lock.ExitWriteLock();
    }
}

公共无效GoThroughAllItems()
{
    this.@lock.EnterReadLock();

    尝试
    {
        foreach(this.Items 中的项目项)
        {
#如果选项2
            this.@lock.ExitReadLock();
#万一

            //处理item,可能需要很长时间

#如果选项2
            this.@lock.EnterReadLock();
#万一
        }
    }

#如果选项2
    抓住
#万一
#如果选项1
    最后
#万一
    {
        this.@lock.ExitReadLock();
    }
}
4

2 回答 2

0

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

于 2010-09-10T11:59:02.550 回答
0

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

伪代码:

read lock
   foreach oldColl
      populate newColl
exit lock

   foreach newColl
      do things

并且您使用每个项目的锁进行编码将不起作用,因为其他线程可能会修改集合并且会导致错误,因为 foreach 不允许修改集合。

于 2010-09-10T11:25:42.333 回答