更改system.io.port数据接收的事件输出类型

问题描述 投票:2回答:2

我正在构建用于Modbus和串行连接的类库,我需要返回一个字节数组,但是当使用System.IO.Ports中的DataReceived事件时,由于它的类型为空,我无法返回任何字节。另外,我注意到DataReceived没有触发。以下是我的代码:

        public void ConnectSerialModBus_Loopback(string COM, int baud, int meter_address, int function, int Code_HighByte, int Code_LowByte, int data_high_byte, int data_low_byte)
    {
        SerialPort port = new SerialPort(COM, baud);
        try
        {

            if (!(port.IsOpen))
            {
                byte[] sendPacket = BuildPacket(meter_address, function, Code_HighByte, Code_LowByte, data_high_byte, data_low_byte);
                double dataBytes = 2.0;

                port.Open();
                port.RtsEnable = false;//rts = high
                port.Handshake = Handshake.None;
                //SEND PACKET TO DEVICE
                port.Write(sendPacket, 0, sendPacket.Length);

                #region RECEIVE DATA FROM SERIAL
                //MAKE DELAY TO SEND
                Thread.Sleep(10);

                port.RtsEnable = true;
                //MAKE DELAY TO RECEIVE
                port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
                //Thread.Sleep(CalculateDelay(dataBytes)+90);

                port.Close();
                port.Dispose();
                #endregion

            }
        }
        catch (Exception ex)
        {
            throw ex;
        }
        finally
        {
            if (port != null)
            {
                if (port.IsOpen)
                {
                    port.Close();
                }
                port.Dispose();
            }
        }
    }

    void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        SerialPort port = (SerialPort)sender;
        byte[] readingbyte = new byte[port.BytesToRead];
        if (port.BytesToRead > 0)
        {
            port.Read(readingbyte, 0, readingbyte.Length);   
        }
    }

以某种方式,我想返回从port_DataReceivedConnectSerialModBus_Loopback接收到的字节,但DataReceived不会触发。请帮助,这非常紧急

c# serial-port .net modbus
2个回答
22
投票

DataReceived未触发

DataReceived不会触发,因为您在附加处理程序之后并在SerialPort的接收线程有机会运行之前立即调用port.Close()

返回字节数组-简单答案

在您提供的简单代码示例中,您可以创建一个私有Byte[]成员,并从readingbyte事件处理程序中为其分配port_DataReceived对象。

返回字节数组-OO提示答案

但是,在更鲁棒的应用程序中,您应该考虑创建一个封装Modbus ADU协议部分的Transaction类,处理客户端请求的传输和服务器响应的(第2层)处理。

除了ADU层,您还将PDU层分离成一个抽象的ModbusFunction基类,该基类为ADU类提供了一个接口,以获取请求字节并返回响应字节。然后,您希望您的客户端使用的每个modbus函数都将在其自己的类中实现,该类是从PDU基类派生的。]

这样,当您需要与服务器进行交互时,您将创建PDU函数类的实例,并使用适当的参数来形成正确的PDU数据包,并将其传递给处理请求/重试/响应的Transaction对象。逻辑,并将返回的数据传递回PDU对象以进行适当的解析。

在PDU基类中添加事件将使代码的其他部分可以附加到PDU类的事件并在函数成功完成后接收通知。

对于具有通过Modbus函数实现的具有多个可寻址属性的服务器,您将为每个属性(例如,为连续寄存器设置的属性)创建适当的Modbus Function类的实例,并将其附加到事件,更新每当对象引发其更新事件时,您的模型和/或UI。如果要手动查询服务器,请挂钩UI命令以将Properties Modbus Function对象传递给Transaction对象,或者如果希望定期对属性进行轮询,请实现一个按计划执行的计时器线程。


0
投票
请勿休眠接收数据的事件。
© www.soinside.com 2019 - 2024. All rights reserved.