我是一个UART设备,我写了一个命令(通过System.IO.Ports.SerialPort),然后设备立即响应。
基本上我的方法是:
- >写入SerialPort-> await Task.Delay->从端口读取。
//The port is open all the time.
public async byte[] WriteAndRead(byte[] message){
port.Write(command, 0, command.Length);
await Task.Delay(timeout);
var msglen = port.BytesToRead;
if (msglen > 0)
{
byte[] message = new byte[msglen];
int readbytes = 0;
while (port.Read(message, readbytes, msglen - readbytes) <= 0)
;
return message;
}
这在我的电脑上运行正常。但是,如果我在另一台计算机上尝试,例如,bytesToRead属性有时会不匹配。其中有空字节或答案未完成。 (例如,我得到两个字节,如果我期望一个字节:0xBB,0x00或0x00,0xBB)
我也查看过SerialPort.DataReceived事件,但它经常触发,并且(据我所知)对于这种写入和读取方法并不真正有用。 (正如我希望设备立即得到答案)。
是否有更好的写入和读取方法?
答案 0 :(得分:0)
仔细阅读implementation中的备注 您不应该依赖BytesToRead值来指示消息长度。 您应该知道,您希望读取多少数据来分解消息。 另外,正如@ itsme85注意到的那样,你没有更新readbytes,因此你总是把接收到的字节写入数组的开头。更新readbytes的正确代码应如下所示:
int r;
while ((r = port.Read(message, readbytes, msglen - readbytes)) <= 0){
readbytes += r;
}
但是,在您阅读数据的过程中,可能会收到更多数据,并且您的消息会被发送到#34;可能不完整。 重新思考,你想要实现的目标。