这是我的代码示例
internal static class Communication
{
...
private static byte _lastAnswer;
...
static void Serial_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
try
{
lock (SerialDataLock)
{
...
_lastAnswer = data[0];
...
}
}
}
}
Serial_DataReceived
是SerialPort.DataReceived
事件的处理程序,数据是从串行端口获取的本地字节数组。问题在于_lastAnswer
的意外行为。调试器显示有时它没有被分配,有时它被分配但是在块的末尾突然返回它的先前值。
例如,我尝试通过主线程
中的公共属性读取_lastAnswer
public static byte LastAnswer
{
get
{
Program.DataRecievedEvent.Reset();
byte rtn = _lastAnswer;
_lastAnswer = ErrorCode;
Debug.Assert(rtn!=0xff);
_lastAnswer = 0xff; //return member to default value
return rtn;
}
}
Assert
不会抛出任何异常,但Main if (answer == 0xff)
中的下一个块返回true
经过一天的发现,我发现在其他非静态类中使字段_lastAnswer
非静态并引用它可以解决问题。但这看起来很糟糕,并没有回答这个话题。
答案 0 :(得分:0)
您正在访问变量而不锁定它。这可能有许多问题。
第二个代码段中没有引入内存障碍,因此允许CPU在多线程上下文中进行不合法的优化。 (它可以使用变量的缓存值,而不会像您认为的那样经常更新它们。)
在您第一次抓住变量并且在第二次抓取变量之前,没有任何东西阻止第一个代码段变异。
在第二个代码段中访问变量时,您应该锁定在第一个代码段中操作变量时锁定的同一个对象。