C# 锁定、属性和权限
当需要多线程访问时,我一直在值类型属性上使用锁定。另外,我一直想更加努力地应用适当的访问修饰符,特别是在我的库代码中,它开始在多个项目中变得有用。我已经编写了一些代码,并希望请求对其中的属性和锁定它们包装的成员变量的各种策略的评论。谢谢。
using System; public class Program { static void Main(string[] args) { SomeValueType svt = new SomeValueType(); SomeReferenceType srt = new SomeReferenceType(); PermissionsAndLocking p = new PermissionsAndLocking(5, svt, srt); //Invalid. //p.X = 6; //Invalid //p.Svt = new SomeValueType(); //Invalid //p.Svt.X = 1; //Valid, but changes a copy of p.Svt because Svt is a value type. SomeValueType svt2 = p.Svt; svt2.X = 7; //Invalid //p.Srt = new SomeReferenceType(); //Valid, change the member data of p.Srt. p.Srt.X = 8; SomeReferenceType srt2 = p.Srt; srt2.X = 9; Console.WriteLine("Press the any key."); Console.Read(); } } public class PermissionsAndLocking { //_x cannot be changed outside the class. //_x cannot be changed "at the same time" it is being accessed??? private readonly object _xLock = new object(); private int _x; public int X { get { lock (_xLock) { return _x; } } private set { lock (_xLock) { _x = value; } } } //_svt and its members cannot be assigned to outside the class. //_svt cannot be changed "at the same time as" it is being accessed. private readonly object _svtLock = new object(); private SomeValueType _svt; public SomeValueType Svt { get { lock (_svtLock) { return _svt; } } private set { lock (_svtLock) { _svt = value; } } } //private on set works for = but member data can still be manipulated... //Locking isn't complete because the reference is returned and can be accessed at a later time??? private readonly object _srtLock = new object(); private SomeReferenceType _srt; public SomeReferenceType Srt { get { lock (_srtLock) { return _srt; } } private set { lock (_srtLock) { _srt = value; } } } public PermissionsAndLocking(int x, SomeValueType svt, SomeReferenceType srt) { _x = x; _svt = svt; _srt = srt; } } public struct SomeValueType { public int X; } public class SomeReferenceType { public int X; }
I've been using lock on value type properties when multi-threaded access is required. Also, I've been meaning to become more diligent about applying proper access modifiers, especially in my library code that is starting to become useful in multiple projects. I've written some code and would like to request comments on the various strategies in it for properties and locking the member variables they wrap. Thanks.
using System; public class Program { static void Main(string[] args) { SomeValueType svt = new SomeValueType(); SomeReferenceType srt = new SomeReferenceType(); PermissionsAndLocking p = new PermissionsAndLocking(5, svt, srt); //Invalid. //p.X = 6; //Invalid //p.Svt = new SomeValueType(); //Invalid //p.Svt.X = 1; //Valid, but changes a copy of p.Svt because Svt is a value type. SomeValueType svt2 = p.Svt; svt2.X = 7; //Invalid //p.Srt = new SomeReferenceType(); //Valid, change the member data of p.Srt. p.Srt.X = 8; SomeReferenceType srt2 = p.Srt; srt2.X = 9; Console.WriteLine("Press the any key."); Console.Read(); } } public class PermissionsAndLocking { //_x cannot be changed outside the class. //_x cannot be changed "at the same time" it is being accessed??? private readonly object _xLock = new object(); private int _x; public int X { get { lock (_xLock) { return _x; } } private set { lock (_xLock) { _x = value; } } } //_svt and its members cannot be assigned to outside the class. //_svt cannot be changed "at the same time as" it is being accessed. private readonly object _svtLock = new object(); private SomeValueType _svt; public SomeValueType Svt { get { lock (_svtLock) { return _svt; } } private set { lock (_svtLock) { _svt = value; } } } //private on set works for = but member data can still be manipulated... //Locking isn't complete because the reference is returned and can be accessed at a later time??? private readonly object _srtLock = new object(); private SomeReferenceType _srt; public SomeReferenceType Srt { get { lock (_srtLock) { return _srt; } } private set { lock (_srtLock) { _srt = value; } } } public PermissionsAndLocking(int x, SomeValueType svt, SomeReferenceType srt) { _x = x; _svt = svt; _srt = srt; } } public struct SomeValueType { public int X; } public class SomeReferenceType { public int X; }
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您需要阅读有关多线程和并发的内容。锁定是为了在不变量无效时保护不变量,即,当不变量无效时,防止并发访问不变量所依赖的共享内存。第一步是了解您的代码例程具有哪些不变量,其次,在哪个代码块中,不变量是无效的。
例如,属性获取器没有内在需要与锁同步。它仅读取属性值。当读取正在进行时,什么不变量是无效的?读取变量、递增变量,然后将递增的值写回属性的操作可能需要锁定,但锁定单个 getter 和 setter 是完全不够的。整个操作(包括读取和写入)必须位于受保护的块内。
You need to read about multi-threading and concurrency. Locking is about protecting invariants whilst they are invalid, i.e., while an invariant is invalid, prevent concurrent access to the shared memory that the invariant is dependant upon. The first step is to understand what invariant your code routine has, and secondly, within which block of code is the invariant invalid.
For example, a property getter has no intrinsic need to be synchronized with a lock. It only reads the property value. What invariant is invalid while this read is going on ? An operation that reads the variable, increments it, and then writes the incremented value back to the property might need to be locked, but locking the individual getter and setter would be totally inadequate. The entire operataion, including the read and the write, would have to be inside the protected block.
锁定
静态对象,因此您应该将_svtLock
标记为静态,以便锁定生效。_x
无法在类外部进行更改。真的。必须通过X
更改它。_x
在访问时无法更改。lock
a static object, so you should mark_svtLock
as static in order for the lock to have an effect._x
cannot be changed outside the class. True. It must be changed viaX
._x
can't be changed at the time it's accessed.