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 - Fatal编程技术网

C# 线程安全类型

C# 线程安全类型,c#,multithreading,C#,Multithreading,我面临的问题是,此代码: enumerable.OfType<Foo>().Any(x => x.Footastic == true); enumerable.OfType().Any(x=>x.Footastic==true); 不是线程安全的,并引发枚举已更改异常 有没有克服这个问题的好办法 已经尝试了以下方法,但并不总是有效(似乎不经常开火) 公共类Foo { 公共无效DoSomeMagicWithCollection(IEnumerable可枚举) { 锁(可枚举)

我面临的问题是,此代码:

enumerable.OfType<Foo>().Any(x => x.Footastic == true);
enumerable.OfType().Any(x=>x.Footastic==true);
不是线程安全的,并引发枚举已更改异常

有没有克服这个问题的好办法

已经尝试了以下方法,但并不总是有效(似乎不经常开火)

公共类Foo
{
公共无效DoSomeMagicWithCollection(IEnumerable可枚举)
{
锁(可枚举)
{
Any(x=>x.Footastic==true);
}
}
}

如果在枚举基础集合时遇到异常,即基础集合已更改,鉴于此代码显然没有改变集合本身,这意味着在您尝试迭代集合时,另一个线程正在改变集合

除了不这样做之外,这个问题没有可能的解决办法。发生的情况是,
列表
(或任何集合类型)的枚举器正在抛出异常并阻止进一步枚举,因为它可以看到列表在枚举过程中被修改。任何的类型的的枚举器都无法从中恢复。基础枚举数拒绝向他们提供列表中的数据。他们对此无能为力

您需要使用某种类型的同步机制来防止另一个线程变异此线程正在枚举此集合的集合wnile。您的
不会阻止另一个线程使用该集合,它只是阻止锁定同一实例的任何代码运行。您需要有任何可能使列表发生变化的代码也锁定在同一个对象上,以便正确地同步它们


另一种可能是使用一个集合,该集合本质上设计为可以同时从多个线程访问。
System.collections.Concurrent
命名空间中有几个这样的集合。它们可能适合您的需要,也可能不适合您的需要。他们将自行负责同步对数据的访问(到某个点),而无需在访问数据时显式锁定。

在这种情况下,什么是
可枚举的
?如果您试图对一个根本不安全的集合进行迭代,那么无论您做什么都会遇到问题。请注意,类型的
不是罪魁祸首。只有在某些代码更改了可枚举项时,才会出现此错误。您发布的代码看起来不是线程安全的。你到底从哪里得到这个例外?什么是调用堆栈?如何创建IEnumerable?您是否有其他代码从另一个线程修改可枚举项?无论您对可枚举项执行任何操作,都需要一个锁对象。您正在其他地方修改可枚举项而不使用锁。@JonSkeet enumerable将是一个具有以下定义的自定义列表:''ObservableStoredList:IList,IList,IEnumerable,INotifyPropertyChanged,INotifyCollectionChanged'@Kevin如果您使用线程安全集合之一,则不需要。在任何情况下,如果其他代码无意中修改了可枚举项,解决方案是删除它,而不是添加锁。您建议从
System.Collections.Concurrent
命名空间中的哪个类替换我当前的
公共类observesOrtedList的类定义:IList、IList、IEnumerable、INotifyPropertyChanged、,INotifyCollectionChanged
with?@RandRandom考虑到我不知道您在对集合做什么,我不可能说,这就是为什么我没有命名类,我只是命名了名称空间。显然,没有一个集合实现所有这些接口。
public class Foo
{
    public void DoSomeMagicWithCollection(IEnumerable enumerable)
    {
        lock (enumerable)
        {
            enumerable.OfType<Foo>().Any(x => x.Footastic == true);
        }
    }
}