我有比赛条件或类似的东西。我的意思是如果我在从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.
奇怪,但它适用于少量字节(对于短消息),但不会持续很长时间。
请,建议。
答案 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)