Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/266.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#_Properties_Thread Safety - Fatal编程技术网

C# 锁定属性而不复制数据

C# 锁定属性而不复制数据,c#,properties,thread-safety,C#,Properties,Thread Safety,我想访问可以被其他代码修改的属性,并确保对它的访问是线程安全的。当然,这个问题已经解决了 然而,在我的特殊情况下,我有不同的具体关切。首先,多线程访问/修改场景可能很少出现,在这种情况下我不会担心性能。而且,这个属性本身相当大——它是一个不和谐的浮动数组,大小可以达到4096乘4096,我希望尽可能少地复制它。最后,我希望类接口易于使用——事实并非如此,因为它需要用户隐式锁定一个特殊的SyncRoot 是否有一种解决方案可以使我的属性线程安全,不需要额外的复制,并且允许客户端使用getter(s

我想访问可以被其他代码修改的属性,并确保对它的访问是线程安全的。当然,这个问题已经解决了

然而,在我的特殊情况下,我有不同的具体关切。首先,多线程访问/修改场景可能很少出现,在这种情况下我不会担心性能。而且,这个属性本身相当大——它是一个不和谐的浮动数组,大小可以达到4096乘4096,我希望尽可能少地复制它。最后,我希望类接口易于使用——事实并非如此,因为它需要用户隐式锁定一个特殊的SyncRoot


是否有一种解决方案可以使我的属性线程安全,不需要额外的复制,并且允许客户端使用getter(setter是私有的),而不必记住锁定任何东西?

如果您想使用方便,.NET提供了内置的线程安全集合类来为您处理锁定

你可以喝一杯

ConcurrentBag<float[]>
ConcurrentBag
如果你自己动手,我会更担心未来的意外死锁,而不是性能。当您开始在类外打开锁定时,死锁是一个非常真实的风险。

参考操作是。因此,如果您确保使用捕获的实例和集合本身是不可变的(其元素不会以任何方式被更改),则仅从集合读取是线程安全的

ICollection SomeProperty{get;set;}
//好
var property=SomeProperty;//捕获
变量a=属性[1]+。。。
//不太好
对于(int i=0;i
如果要设置新集合,请先填充它,然后再设置。如果只想更改一个元素-创建新集合,请填充并设置它

void AddItem(SomeType item)
{
    var collection = new ICollection<SomeType>(SomeProperty); // copy old content
    collection.Add(item);
    SomeProperty = collection;
}
void AddItem(SomeType项)
{
var collection=new ICollection(SomeProperty);//复制旧内容
集合。添加(项目);
SomeProperty=集合;
}
你也应该只有一个作家。在
AddItem()
中,至少有一个需要某种类型的同步:
lock


IDisposable
元素有问题。但是这种想法(捕获+不可变)对于具有多个读卡器和罕见写入器的场景中的简单类型应该非常有效,因为不需要同步。

如果它很少更改,并且您使用的是.NET 4.5,那么您可以使用ReadOnlyCollection并在getter中返回它。然后使用一个单独的“SetUpdatedCollection”方法或类似方法,该方法将丢弃旧的ReadOnlyCollection并创建一个新的ReadOnlyCollection。在getter和SetUpdatedCollection方法中使用内部锁对象,将强制执行并发。锯齿数组是在其他线程上“调整大小”,还是只修改其内容?调整大小的情况要复杂得多,因为您不仅需要担心同步对数据的访问,还需要担心任何缓存读取的大小。@user469104由于我无法控制的原因(Unity3d),我被锁定到.NET 2.0。这是关于集合的一个很好的答案。它也适用于数组吗?为什么会有任何区别?数组的结构更简单。
void AddItem(SomeType item)
{
    var collection = new ICollection<SomeType>(SomeProperty); // copy old content
    collection.Add(item);
    SomeProperty = collection;
}