将这些枚举/开始枚举队列
本文关键字:枚举 开始 队列 | 更新日期: 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操作符(在您的例子中是Any
、FirstOrDefault
和Except
)不会更改集合,因此它们不会抛出。
您显示的所有操作都会枚举队列,因此您无法在这些操作中更改它,因此它不是线程安全的(这取决于您锁定队列更新操作的方式)。
如果需要保护枚举,则需要更高级别的锁定层。
为了达到最佳效果,为了避免在已有读卡器的情况下锁定新的读卡器,您可以使用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个并行枚举,但在任何给定时间只有一个更新运行。