我正在为modbus和串行连接构建一个类库,我需要返回一个字节数组,但是当使用System.IO.Ports中的DataReceived事件时,由于它的类型为void,我无法返回任何内容。此外,我注意到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_DataReceived
或ConnectSerialModBus_Loopback
收到的字节,而DataReceived也没有触发。请帮忙这是非常紧急的
答案 0 :(得分:22)
DataReceived未触发
DataReceived未触发,因为您在附加处理程序之后以及在SerialPort的接收线程有机会运行之前立即调用port.Close()
。
返回一个字节数组 - 简单回答
在您提供的简单代码示例中,您可以创建一个私有Byte[]
成员,并从readingbyte
事件处理程序中为其分配port_DataReceived
对象。
返回一个字节数组 - OO提示回答
但是,在更多的rubust应用程序中,您应该考虑创建一个封装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对象,或者如果希望定期轮询属性,则实现按计划执行它的计时器线程。 p>
答案 1 :(得分:0)