将这些枚举/开始枚举队列

本文关键字:枚举 开始 队列 | 更新日期: 2023-09-27 18:19:44

我有一个可以从不同线程访问的静态队列。

队列实现了一个包装器,该包装器在添加/删除/设置时正确锁定。还有一种方法,我锁定并返回Queue的副本,但这会使一个新的枚举成为可能,这有点浪费,所以我只想在必要时调用它。

我不想不必要地复制队列,但如果在.中枚举时队列发生了更改,则对其进行枚举可能会引发异常

有没有可能在枚举时抛出异常(当然是因为上面的原因):

  • QueueWrapper.InnerQueue.Any()(任意为空)
  • QueueWrapper.InnerQueue.FirstOrDefault(o => o.Something)
  • QueueWrapper.InnerQueue.Except(element)

我应该在哪里用QueueWrapper.GetQueueCopy()替换QueueWrapper.InnerQueue

将这些枚举/开始枚举队列

枚举仅在更改基础集合时抛出。LINQ操作符(在您的例子中是AnyFirstOrDefaultExcept)不会更改集合,因此它们不会抛出。

您显示的所有操作都会枚举队列,因此您无法在这些操作中更改它,因此它不是线程安全的(这取决于您锁定队列更新操作的方式)。

如果需要保护枚举,则需要更高级别的锁定层。

为了达到最佳效果,为了避免在已有读卡器的情况下锁定新的读卡器,您可以使用ReaderWriterLockSlim(http://msdn.microsoft.com/library/system.threading.readerwriterlockslim.aspx)。

你会有这样的代码:

ReaderWriterLockSlim rwls = new ReaderWriterLockSlim();
...
rwls.EnterReadLock();
try
{
    // some enumeration
}
finally
{
    rwls.ExitReadLock();
}
...
rwls.EnterWriteLock();
try
{
    // some bulk update
}
finally
{
    rwls.ExitWriteLock();
}

通过这种方式,您可以有n个并行枚举,但在任何给定时间只有一个更新运行