【问题标题】:C# Locking, Properties & PermissionsC# 锁定、属性和权限
【发布时间】: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格式化:stackoverflow.com/editing-help 特别是代码需要缩进4个空格才能正确格式化。
  • “我一直在对值类型属性使用锁定” - 希望您的意思是引用类型。
  • @TrueWIll,他的意思是“保护”值类型属性...

标签: c# properties locking modifiers


【解决方案1】:

您需要阅读有关多线程和并发的信息。锁定是关于在不变量无效时保护不变量,即,当不变量无效时,防止并发访问不变量所依赖的共享内存。第一步是了解您的代码例程具有哪些不变量,其次,在 哪个 代码块中不变量是无效的。

例如,属性 getter 没有内在的需要与锁同步。它只读取属性值。进行此读取时,哪些不变量无效?读取变量、递增变量,然后将递增的值写回属性的操作可能需要锁定,但锁定单独的 getter 和 setter 是完全不够的。整个操作,包括读取和写入,都必须在受保护的块内。

【讨论】:

  • 确实,在这种情况下,我有一个线程正在更改而另一个线程正在访问的数据。数据通过属性提供。我正在研究是否可以使用锁定来协调访问。
  • 第二段的优点。有点像带有比较/交换方法的互锁类。一次性完成,全部锁定。所以,知道了这一点,你会说锁定和属性不能很好地混合。有没有办法正确处理属性?
  • @Nate,不,不可能。多线程和并发太复杂了,以至于不能允许那种接近金属的“一刀切”的方法。您必须分析您正在编码的每个功能操作,以确定是否暴露了易受攻击的共享内存。解决问题的适当机制几乎总是在很大程度上取决于场景,而且很少是微不足道的。
【解决方案2】:
  1. 您应该始终lock 一个静态对象,因此您应该将_svtLock 标记为静态,以使锁定生效。
  2. _x 不能在课堂外更改。真的。必须通过X 更改。
  3. 如果您正确实施了锁定(参见 1),则 _x 在访问时无法更改。

【讨论】:

  • 所以锁对象应该永远是静态的?如果我有一个非静态类,并且我希望只锁定对该对象内成员数据的访问,该怎么办。我不想绑定该类型的所有对象,因为它们正在等待释放锁。
  • @Ngu -1 有几个错误。仅仅因为一个对象是静态的并不足以要求一个锁。私有静态只读 int pi = 3.1415;这个不用锁了吧? 2.“正确”实现锁,并不意味着共享内存(_x)不能改变。事实上,它根本不会阻止变量被更改。仅当可能更改 _x 的所有其他代码块也位于使用完全相同的锁引用的锁块内时,才可以保证。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-08
  • 1970-01-01
  • 2011-04-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多