代码之家  ›  专栏  ›  技术社区  ›  Ricardo Peres

在.NET中同步读写集合

  •  -1
  • Ricardo Peres  · 技术社区  · 14 年前

    我有一个对象,它保存着一组项目。我希望能够通过additem方法向集合中添加项,并且能够遍历集合中的所有项。我的对象必须是线程安全的。我正在使用读写器LockSlim来确保正确的同步。 如何同步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 回复  |  直到 14 年前
        1
  •  0
  •   Andrey    14 年前

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

    伪代码:

    read lock
       foreach oldColl
          populate newColl
    exit lock
    
       foreach newColl
          do things
    

    而且,对每个项使用锁的代码将无法工作,因为其他线程可能会修改集合,并且会导致错误,因为foreach不允许修改集合。

        2
  •  0
  •   Bernd    14 年前

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