Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/297.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 更改system.io.port datareceived事件输出类型_C#_Serial Port_.net_Modbus - Fatal编程技术网

C# 更改system.io.port datareceived事件输出类型

C# 更改system.io.port datareceived事件输出类型,c#,serial-port,.net,modbus,C#,Serial Port,.net,Modbus,我正在为modbus和串行连接构建一个类库,我需要返回一个字节数组,但当使用System.IO.Ports的DataReceived事件时,我无法返回任何字节,因为它的类型为void。另外,我注意到接收到的数据没有触发。以下是我的代码: public void ConnectSerialModBus_Loopback(string COM, int baud, int meter_address, int function, int Code_HighByte, int Code

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

        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);   
        }
    }

在某种程度上,我想返回从
端口\u DataReceived
或从
ConnectSerialModBus\u环回
接收到的字节,并且接收到的数据没有触发。请帮助这是非常紧急的

不要休眠datareceived事件

事件激发时,将字节放入队列中。您将需要UI可以用来将字节块重新组合在一起的方法


有关此操作的更多详细信息,请参阅。

接收到的数据未触发。

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

返回字节数组-简单回答

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

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

<>但是,在一个更广泛的应用程序中,您应该考虑创建一个封装Modbus ADU协议部件的事务类,处理客户端请求的传输和(第2层)服务器响应的处理。 除了ADU层之外,您还可以将PDU层分离为一个抽象的ModbusFunction基类,该基类为ADU类提供一个接口,用于获取请求字节和返回响应字节。然后,您希望客户机使用的每个modbus功能将在其自己的类中实现,该类派生自PDU基类

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

向PDU基类添加事件将允许代码的其他部分附加到PDU类的事件,并在函数成功完成时接收通知

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