[英]SerialPort.DataReceived repeatedly subscribe/unsubscribe
我正在使用串行端口与远程诊断设备进行通信。
来自远程设备的响应的长度取决于命令,但是会提前知道。 因此,当前我发送命令并等待接收所需数量的响应字节。
每当我不主动请求数据时,我都订阅“ SerialPort.DataReceived”事件。 此事件的处理程序只是将所有“未经请求的”接收到的数据转储到日志中(通常仅在远程设备意外重启时才接收未经请求的数据,等等)。
在某些情况下,我想以大约60Hz的速率发送命令。
我的问题是,每次我调用我的“ SendCommand”方法主动请求数据时,最好退订/订阅“ SerialPort.DataReceived”事件,还是我应该单独保留事件订阅并仅切换一个布尔型“ TransferInProgress”标志,当我主动请求DataReceived处理程序时,它可以用来忽略传入的数据吗?
这是当前的实现:
public virtual bool SendCommand(byte[] command, ref byte[] response) {
try {
TransferInProgress = true;
OnTransferStarted();
// temporarily unsubscribe since we're actively soliciting data
_port.DataReceived -=
new SerialDataReceivedEventHandler(SerialPort_DataReceived);
_port.DiscardInBuffer();
_port.Write(command, 0, command.Length);
OnCommandSent(command);
// read the requested number of response bytes
int responseBytesRead = 0;
while (responseBytesRead < response.Length) {
responseBytesRead +=
_port.Read(response, responseBytesRead, (response.Length - responseBytesRead));
}
OnCommandResponseReceived(response);
return true;
}
catch (Exception ex) {
OnCommandSendFailed(ex.Message);
return false;
}
finally {
_port.DataReceived +=
new SerialDataReceivedEventHandler(SerialPort_DataReceived);
OnTransferComplete();
TransferInProgress = false;
}
}
-特雷弗
如果我理解正确,我的看法是仅在DataReceived处理程序中处理所有接收数据,或者您有其他选择。
如果实际请求之间收到的数据不多,您可以在发送请求之前先读取缓冲区并记录下来。 串行驱动程序接收缓冲区可能足以存储少量数据。 然后发送请求并仅读入响应。 这可能是更简单的方法和更简单的代码。
我通常切换一个布尔值。 订阅/取消订阅会使您面临多次订阅同一事件的风险。 例如,在代码中,如果OnTransferStarted()
引发异常,则您将订阅两次DataReceived
事件。
您是否考虑过在一个地方处理所有数据接收? 您可以将发送的命令视作一发不可收拾,分析收到的响应数据。 如果响应没有标识性的标头,并且知道如何解析响应的唯一方法是知道发送的命令和响应的长度,则可以跟踪队列中发送的命令。 可行的方式是,在“数据接收”处理程序中,您将检查等待响应的命令队列,然后像现在一样解析接收到的数据。
长话短说,我建议在一个地方处理所有传入的数据。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.