串行COM端口仅在调试中有效

时间:2014-10-27 18:22:46

标签: c# .net multithreading serial-port race-condition

我有比赛条件或类似的东西。我的意思是如果我在从COM读取之前切换断点,一切都很好。但是当我把它切换掉时,它会冻结。写作:

    public void Send(ComMessage message)
    {
        byte[] bytes = message.Serialise();
        if (!_outputPort.IsOpen)
            _outputPort.Open();
        try
        {
            byte[] size = BitConverter.GetBytes(bytes.Length);
            _outputPort.Write(size, 0, size.Length);
            _outputPort.Write(bytes, 0, bytes.Length);
        }
        finally
        {
            if (_outputPort != _inputPort)
                _outputPort.Close();
        }
    }

    private void InputPortOnDataReceived(object sender, SerialDataReceivedEventArgs serialDataReceivedEventArgs)
    {
        var port = (SerialPort) sender;

        byte[] sizeBuffer = new byte[sizeof(long)];
        port.Read(sizeBuffer, 0, sizeBuffer.Length);
        int length = BitConverter.ToInt32(sizeBuffer, 0);
        byte[] buffer = new byte[length];

        int i = 0;
        while (i < length)
        {
            int readed = port.Read(buffer, i, length - i);
            i += readed;
        }


        var message = ComMessage.Deserialize(buffer);
        MessageReceived(this, message);
    }
例如,

消息的长度为625字节。如果我切换断点,port.BytesToRead等于625,但如果我禁用它,则字节数为621.

奇怪,但它适用于少量字节(对于短消息),但不会持续很长时间。

请,建议。

1 个答案:

答案 0 :(得分:1)

  

消息长度为625字节。如果我切换断点,   port.BytesToRead等于625,但如果我禁用它,则字节数为621。

您永远不会检查第一个Read以查看它读取的字节数。它可能读取的字节数少于sizeof(long)。但是,这不是问题的根源,您的主要问题是您正在制作大小为long但长为Int64的缓冲区,您正在呼叫ToInt32(并在发件人中写Int32)。

您的字节数为261而不是265的原因是因为您的邮件的前4个字节位于您从未处理过的sizeBuffer[4]sizeBuffer[7]

要解决此问题,您应该执行sizeof(int)或更好地使缓冲区更适合ToInt32调用,使用sizeof(Int32)