Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 这些将枚举/开始枚举队列吗?_C#_Multithreading_Enumeration - Fatal编程技术网

C# 这些将枚举/开始枚举队列吗?

C# 这些将枚举/开始枚举队列吗?,c#,multithreading,enumeration,C#,Multithreading,Enumeration,我有一个可以从不同线程访问的静态队列 队列实现了一个包装器,它在add/remove/set上正确锁定。 还有一种方法,我锁定并返回队列的一个副本,但这会使一个新的枚举成为可枚举的,这有点浪费,所以我只想在必要时调用它 我不想不必要地复制队列,但如果在中枚举时更改了队列,则对其进行枚举会引发异常 是否有可能在枚举时引发异常(当然是由于上述原因): QueueWrapper.InnerQueue.Any()(清空Any) QueueWrapper.InnerQueue.FirstOrDefaul

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

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

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

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

  • QueueWrapper.InnerQueue.Any()
    (清空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
)此代码,并且您需要它是线程安全的,那么,是的,不可变集合是一种方法。但是,如果可以选择同步代码,那么应该从同步代码开始。在这种情况下,上述解释仍然有效。