c#多窗口输出串口接收到的信息

c#多窗口输出串口接收到的信息

Amiron 346 2022-04-05

c#多窗口输出串口接收到信息

在用c#写上位机软件时,通常需要将串口接收到的信息输出到界面。在需求简单的情况下,可以直接单窗口输出信息,但是在需求复杂时,需要对串口进行复用。这种情况下,就不能简单的直接输出信息了。

过程

一、 通过接口实现回调输出信息方法

整体思路:定义一个含有输出方法的接口A;在串口类中用接口A声明一个对象,并在串口接收事件中,调用接口A中的输出方法;窗口类实现接口A,并将自己赋给串口类中的接口A对象,使它们之间建立回调联系。

定义接口A

public interface ICommunicationLog
{
	void showLogMessage(string message);
}

串口类

public class MySerialPort
    {
        private SerialPort serialPort = new SerialPort();
        public ICommunicationLog communicationLog;
		...  
        private void SerialPortDataReceived(object sender, SerialDataReceivedEventArgs e)
        {

	....
	// 调用输出方法
    if (communicationLog != null) communicationLog.showLogMessage(byteToHexStr(bytebuffer));
    
        }
    }

窗口类

  public partial class MainForm : Form, ICommunicationLog
    {
        private MySerialPort serialPort;
      ...
      
        private void buttonOpen_Click(object sender, EventArgs e)
        {
            serialPort = new MySerialPort();
            ...
            serialPort.communicationLog = this;
            ...
        }

        private void showLog(string msg)
        {
            Invoke(new Action(() => textBoxLog.AppendText(msg + "\r\n")));
        }

		// 接口A输出方法
        public void showLogMessage(string message)
        {
            showLog(message);
        }
    }

结尾

虽然能基本实现需求,但还是不够灵活,当需求变得越来越复杂时,弊端也会浮现出来。

二、使用Action事件实现

基本思路: 使用c#自有的特性实现消息的订阅与发布(不自觉感叹c#天下第一哈哈哈)。串口类中定义一个事件,在串口接收事件中发布消息;在窗口类中订阅串口类中的事件,实现输出消息。

串口类

 public class MySerialPort
    {
        private SerialPort serialPort = new SerialPort();
        public event Action<string> showLogEvent;
		... 
        private void SerialPortDataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            try
            {
				...
                // 发布输出消息
                if (showLogEvent != null) showLogEvent(byteToHexStr(bytebuffer));

            } catch(Exception)
            {
                throw;
            } 
        }

    }

窗口类

public partial class MainForm : Form
    {
        private MySerialPort serialPort;
        ...

        private void buttonOpen_Click(object sender, EventArgs e)
        {
            serialPort = new MySerialPort();
           ...
           // 订阅输出消息
            serialPort.showLogEvent += showLog;

        }
        
        private void showLog(string msg)
        {
            Invoke(new Action(() => textBoxLog.AppendText(msg + "\r\n")));
        }
    }

源码

ShowLogDemo;

参考

c# action使用 事件 订阅与发布


# c#