0

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

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

我不想不必要地复制队列,但是如果在我枚举时队列被更改,那么枚举它可能会引发异常。

这些在枚举时是否有可能引发异常(当然是由于上述原因):

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

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

4

2 回答 2

0

仅当您更改基础集合时才会引发枚举。LINQ 运算符(AnyFirstOrDefaultExcept您的情况下)不会更改集合,因此它们不会抛出。

于 2013-06-25T10:14:38.793 回答
0

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

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

为了达到最佳效果,为避免在已有读者时锁定新读者,您可以使用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 个并行枚举,但在任何给定时间只能运行一个更新。

于 2013-06-25T10:15:06.323 回答