C# 这些将枚举/开始枚举队列吗?
我有一个可以从不同线程访问的静态队列 队列实现了一个包装器,它在add/remove/set上正确锁定。 还有一种方法,我锁定并返回队列的一个副本,但这会使一个新的枚举成为可枚举的,这有点浪费,所以我只想在必要时调用它 我不想不必要地复制队列,但如果在中枚举时更改了队列,则对其进行枚举会引发异常 是否有可能在枚举时引发异常(当然是由于上述原因):C# 这些将枚举/开始枚举队列吗?,c#,multithreading,enumeration,C#,Multithreading,Enumeration,我有一个可以从不同线程访问的静态队列 队列实现了一个包装器,它在add/remove/set上正确锁定。 还有一种方法,我锁定并返回队列的一个副本,但这会使一个新的枚举成为可枚举的,这有点浪费,所以我只想在必要时调用它 我不想不必要地复制队列,但如果在中枚举时更改了队列,则对其进行枚举会引发异常 是否有可能在枚举时引发异常(当然是由于上述原因): QueueWrapper.InnerQueue.Any()(清空Any) QueueWrapper.InnerQueue.FirstOrDefaul
(清空Any)QueueWrapper.InnerQueue.Any()
QueueWrapper.InnerQueue.FirstOrDefault(o=>o.Something)
QueueWrapper.InnerQueue.Except(元素)
我应该在哪里用
QueueWrapper.GetQueueCopy()
替换QueueWrapper.InnerQueue
?枚举仅在更改基础集合时抛出。LINQ操作符(Any
、FirstOrDefault
和在您的情况下除外)不会更改集合,因此它们不会抛出。您显示的所有操作都会枚举队列,因此您在这些操作期间无法更改它,因此它不是线程安全的(这取决于您锁定队列的更新操作的方式)
如果需要保护枚举,则需要更高级别的锁定层
为了达到最佳效果,为了避免在已有读卡器时锁定新读卡器,您可以使用ReaderWriterLockSlim()
您将有如下代码:
ReaderWriterLockSlim rwls = new ReaderWriterLockSlim();
...
rwls.EnterReadLock();
try
{
// some enumeration
}
finally
{
rwls.ExitReadLock();
}
...
rwls.EnterWriteLock();
try
{
// some bulk update
}
finally
{
rwls.ExitWriteLock();
}
通过这种方式,您可以在任何给定的时间运行n个并行枚举,但只有一个更新。我不知道如何回答这个问题,但仅供参考,.NET中有一个并发队列:C4stor是正确的:如果您可以使用内置实现,可以大大简化事情。否:)。但是,如果一个线程调用Any
、First
或Except
,而另一个线程在执行上述方法期间修改了集合,它们会引发异常吗?是的,但这不是您可以准备的。如果您不同步(lock
)此代码,并且您需要它是线程安全的,那么,是的,不可变集合是一种方法。但是,如果可以选择同步代码,那么应该从同步代码开始。在这种情况下,上述解释仍然有效。