繁体   English   中英

SerialPort.DataReceived重复订阅/取消订阅

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM