我正在读一个Guid对象两次,一次是在if语句中,一次是在if语句的块中.
在CI中,将在本地复制变量,以确保if语句中的读取操作不会读取不同的值(如果另一个线程在中间更改此值).
我怀疑以下方法是a)线程安全和b)会给我相同的值:
public class MyClass {
private Guid MyProp {get;set;} = Guid.Empty; //May be changed at will
public OnRunLoop() //Gets called periodicaly on a thread
{
var ALocalCopyOfTheProp = MyProp; //Copy locally
if(ALocalCopyOfTheProp == AValueFromAnotherPlace) //Read 1
{
...
var AnotherReadOfTheVariable = ALocalCopyOfTheProp; //Read 2
}
...
}
Run Code Online (Sandbox Code Playgroud)
C#.NET本身没有谷歌搜索的复制功能,所以在这种情况下最佳做法是什么?
编辑: - 请注意,在这种情况下,MyProp不在我的手中.我不能使用锁,因为该物业来自其他地方.(道歉没有让它更清晰) - Guid是一个结构而不是引用类型
在CI中,会在本地复制变量,以确保if语句中的读取操作不会读取不同的值(如果另一个线程在中间更改此值).
我注意到这种技术只是交换了一个问题 - 不一致的读取 - 另一个问题 - 陈旧的读取.
这种技术在多线程事件处理程序的C#中很常见; 你经常看到类似的东西:
var myEvent = this.MyEvent;
if (myEvent != null) myEvent(whatever);
Run Code Online (Sandbox Code Playgroud)
虽然这确实解决了在调用和调用this.MyEvent之间发生变化的竞争条件的问题if,但它并没有解决更深层次的问题:你可以检查一个线程,在另一个线程上将事件处理程序设置为null,现在假设永远不会再次调用事件处理程序是false,因为将在另一个线程上调用过时的值!
你不能简单地在当地复制东西,希望最好.你要证明的是任何可能重新排序的您读取和写入上的任何数量的线程产生一个合理的方案.
Guid对象是引用类型
绝对不是.
C#.NET本身没有谷歌搜索的复制功能,所以在这种情况下最佳做法是什么?
拿出一把锁.
我不能用锁
然后,您只需要在一个线程上调用您的属性.