C# 锁定、属性和权限
Posted
技术标签:
【中文标题】C# 锁定、属性和权限【英文标题】:C# Locking, Properties & Permissions 【发布时间】:2010-12-02 04:27:15 【问题描述】:当需要多线程访问时,我一直在对值类型属性使用锁定。此外,我一直想更加努力地应用适当的访问修饰符,尤其是在我的库代码中,它开始在多个项目中变得有用。我已经编写了一些代码,并希望请求 cmets 了解其中的各种策略以获取属性并锁定它们包装的成员变量。谢谢。
使用系统; 公开课程序 静态无效主要(字符串 [] 参数) SomeValueType svt = new SomeValueType(); SomeReferenceType srt = new SomeReferenceType(); PermissionsAndLocking p = new PermissionsAndLocking(5, svt, srt); //无效的。 //p.X = 6; //无效的 //p.Svt = new SomeValueType(); //无效的 //p.Svt.X = 1; //有效,但会更改p.Svt的副本,因为Svt是一个值类型。 SomeValueType svt2 = p.Svt; svt2.X = 7; //无效的 //p.Srt = new SomeReferenceType(); //有效,改变p.Srt的成员数据。 p.Srt.X = 8; SomeReferenceType srt2 = p.Srt; srt2.X = 9; Console.WriteLine("按任意键。"); Console.Read(); 公共类 PermissionsAndLocking //_x 不能在类外更改。 //_x 不能“同时”改变它正在被访问??? 私有只读对象 _xLock = new object(); 私人int _x; 公共诠释 X 得到 锁 (_xLock) 返回_x; 私人集 锁 (_xLock) _x = 值; //_svt 及其成员不能分配给类外。 //_svt 不能在被访问的“同时”改变。 私有只读对象 _svtLock = new object(); 私人 SomeValueType _svt; 公共 SomeValueType Svt 得到 锁 (_svtLock) 返回_svt; 私人集 锁 (_svtLock) _svt = 价值; //private on set适用于=,但成员数据仍然可以被操作... //锁定未完成,因为引用被返回,可以稍后访问??? 私有只读对象 _srtLock = new object(); 私人 SomeReferenceType _srt; public SomeReferenceType Srt 得到 锁 (_srtLock) 返回_srt; 私人集 锁 (_srtLock) _srt = 值; public PermissionsAndLocking(int x, SomeValueType svt, SomeReferenceType srt) _x = x; _svt = svt; _srt = srt; 公共结构 SomeValueType 公共诠释 X; 公共类 SomeReferenceType 公共诠释 X;【问题讨论】:
Nate,你需要了解markdown格式化:***.com/editing-help 特别是代码需要缩进4个空格才能正确格式化。 “我一直在对值类型属性使用锁定” - 希望您的意思是引用类型。 @TrueWIll,他的意思是“保护”值类型属性... 【参考方案1】:您需要阅读有关多线程和并发的信息。锁定是关于在不变量无效时保护不变量,即,当不变量无效时,防止并发访问不变量所依赖的共享内存。第一步是了解您的代码例程具有哪些不变量,其次,在 哪个 代码块中不变量是无效的。
例如,属性 getter 没有内在的需要与锁同步。它只读取属性值。进行此读取时,哪些不变量无效?读取变量、递增变量,然后将递增的值写回属性的操作可能需要锁定,但锁定单独的 getter 和 setter 是完全不够的。整个操作,包括读取和写入,都必须在受保护的块内。
【讨论】:
确实,在这种情况下,我有一个线程正在更改而另一个线程正在访问的数据。数据通过属性提供。我正在研究是否可以使用锁定来协调访问。 第二段的优点。有点像带有比较/交换方法的互锁类。一次性完成,全部锁定。所以,知道了这一点,你会说锁定和属性不能很好地混合。有没有办法正确处理属性? @Nate,不,不可能。多线程和并发太复杂了,以至于不能允许那种接近金属的“一刀切”的方法。您必须分析您正在编码的每个功能操作,以确定是否暴露了易受攻击的共享内存。解决问题的适当机制几乎总是在很大程度上取决于场景,而且很少是微不足道的。【参考方案2】:-
您应该始终
lock
一个静态对象,因此您应该将_svtLock
标记为静态,以使锁定生效。
_x
不能在课堂外更改。真的。必须通过X
更改。
如果您正确实施了锁定(参见 1),则 _x
在访问时无法更改。
【讨论】:
所以锁对象应该永远是静态的?如果我有一个非静态类,并且我希望只锁定对该对象内成员数据的访问,该怎么办。我不想绑定该类型的所有对象,因为它们正在等待释放锁。 @Ngu -1 有几个错误。仅仅因为一个对象是静态的并不足以要求一个锁。私有静态只读 int pi = 3.1415;这个不用锁了吧? 2.“正确”实现锁,并不意味着共享内存(_x)不能改变。事实上,它根本不会阻止变量被更改。仅当可能更改 _x 的所有其他代码块也位于使用完全相同的锁引用的锁块内时,才可以保证。以上是关于C# 锁定、属性和权限的主要内容,如果未能解决你的问题,请参考以下文章
C#面向对象字段(Field)和属性(Property)的区别