gpt4 book ai didi

使用 get/set 的 C# 线程安全

转载 作者:IT王子 更新时间:2023-10-29 03:50:40 33 4
gpt4 key购买 nike

这是 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,并非此类的每个设备都具有相同的行为,只是一般行为,因此如果我对锁进行个性化设置,我将不得不编写大量单独的对话框。

最佳答案

不,您的代码不会锁定对从 MyProperty 返回的对象成员的访问。它只锁定 MyProperty 本身。

您的示例用法实际上是将两个操作合二为一,大致相当于:

// object is locked and then immediately released in the MyProperty getter
MyObject o = MyProperty;

// this assignment isn't covered by a lock
o.Field1 = 2;

// the MyProperty setter is never even called in this example

简而言之 - 如果两个线程同时访问 MyProperty,getter 将暂时阻塞第二个线程,直到它将对象返回给第一个线程,但是它会然后将对象也返回给第二个线程。然后,两个线程都将拥有对该对象的完全解锁访问权限。

编辑以回应问题中的更多细节

我仍然不能 100% 确定您要实现的目标,但是如果您只想对对象进行原子访问,那么您不能对对象本身进行调用代码锁定吗?

// quick and dirty example
// there's almost certainly a better/cleaner way to do this
lock (MyProperty)
{
// other threads can't lock the object while you're in here
MyProperty.Field1 = 2;
// do more stuff if you like, the object is all yours
}
// now the object is up-for-grabs again

不理想,但只要对对象的所有访问都包含在 lock (MyProperty) 部分中,那么这种方法就是线程安全的。

关于使用 get/set 的 C# 线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/505515/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com