这是 C# 的详细问题。
假设我有一个带有对象的类,并且该对象受锁保护:
Object mLock = new Object();
MyObject property;
public MyObject MyProperty {
get {
return property;
}
set {
property = value;
}
}
我希望轮询线程能够查询该属性。我还希望线程偶尔更新该对象的属性,有时用户可以更新该属性,并且用户希望能够看到该属性。
以下代码会正确锁定数据吗?
Object mLock = new Object();
MyObject property;
public MyObject MyProperty {
get {
lock (mLock){
return property;
}
}
set {
lock (mLock){
property = value;
}
}
}
'适当地',我的意思是,如果我想打电话
MyProperty.Field1 = 2;
或者其他什么,在我进行更新时该字段会被锁定吗?是在“get”函数范围内由等于运算符完成的设置,还是“get”函数(以及锁定)首先完成,然后调用设置,然后调用“set”,从而绕过锁?
编辑:既然这显然不会奏效,那会怎样?我是否需要做类似的事情:
Object mLock = new Object();
MyObject property;
public MyObject MyProperty {
get {
MyObject tmp = null;
lock (mLock){
tmp = property.Clone();
}
return tmp;
}
set {
lock (mLock){
property = value;
}
}
}
这或多或少只是确保我只能访问副本,这意味着如果我让两个线程同时调用“get”,它们每个都将以相同的 Field1 值开始(对吗?)。有没有办法对有意义的属性进行读写锁定?或者我应该限制自己锁定功能部分而不是数据本身?
只是为了让这个例子有意义:MyObject 是一个异步返回状态的设备驱动程序。我通过串行端口向它发送命令,然后设备在自己的甜蜜时间响应这些命令。现在,我有一个线程来轮询它的状态(“你还在那里吗?你能接受命令吗?”),一个等待串行端口响应的线程(“刚得到状态字符串 2,一切都很好” ),然后是接受其他命令的 UI 线程(“用户希望你做这件事。”)并发布来自驱动程序的响应(“我刚刚完成了这件事,现在用它更新 UI”)。这就是为什么我想锁定对象本身,而不是对象的字段;那将是大量的锁,a 和 b,并非此类的每个设备都具有相同的行为,