0

这是我的代码示例

internal static class Communication
{
    ...

    private static byte _lastAnswer;

    ...

    static void Serial_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        try
        {
            lock (SerialDataLock)
            {
                ...
                 _lastAnswer = data[0];
                ...
            }
        }
    }
}

Serial_DataReceivedSerialPort.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在其他非静态类中设置非静态字段并引用它可以解决问题。但这看起来很糟糕,并没有回答这个话题。

4

1 回答 1

0

您正在访问变量而不锁定它。这可能有很多问题。

  1. 您的第二个代码片段中没有引入内存屏障,因此允许 CPU 进行在多线程上下文中不合法的优化。(它可以使用变量的缓存值,而无需像您认为的那样频繁地更新它们。)

  2. 没有什么可以阻止第一个代码片段在您第一次抓取它之后以及在您第二次抓取它之前改变变量。

在第二个片段中访问变量时,您应该锁定与在第一个片段中操作变量时锁定的对象相同的对象。

于 2013-10-01T17:08:29.780 回答