• 串口应用线程委托实现界面交互的操作方法


    1、构建方法时候,需要用界面来显示串口接收到的数据,所以我才用了,较为复杂的委托事件线程的方法,把串口接收的模块并入到我的主工程中;

    总结一下串口模块的设计,

    新建一个委托

    public delegate void SerialPortEventHandler(Object sender, SerialPortEventArgs e);

    新建一个事件 SerialPortEventArgs类,继承自事件数据的类的基类

    public class SerialPortEventArgs : EventArgs
    {
    public bool isOpend = false;
    public Byte[] receivedBytes = null;
    }

    新建一个ComModel类

       在类中申明事件

        public event SerialPortEventHandler comReceiveDataEvent = null;
        public event SerialPortEventHandler comOpenEvent = null;
        public event SerialPortEventHandler comCloseEvent = null;

        

         private SerialPort sp = new SerialPort();

         private Object thisLock = new Object();

        在串口控件的事件中,有3个事件

                                 

    当串口接收到数据时,触发 DataReceived 事件, 单击产生的方法中加入代码功能:

      1.假如 sp.BytesToRead <= 0 ,返回。

      2.锁住线程  lock (thisLock)

      3.读取数据:  

    1                 int len = sp.BytesToRead;
    2                 Byte[] data = new Byte[len];
    3                 try
    4                 {
    5                     sp.Read(data, 0, len);
    6                 }                

      4.new出来自己定义的事件 SerialPortEventArgs 

          SerialPortEventArgs args = new SerialPortEventArgs(); 

           事件中传送的数据

         args.receivedBytes = data;

       5.如果 事件comReceiveDataEvent ,不为空,则用事件......()

        if (comReceiveDataEvent != null)
        {
          comReceiveDataEvent.Invoke(this, args);
        }

         //用事件通知界面

     新建一个IController的类

      Controller类是Form类和Model类的桥梁,在该Controller中,将界面上的更新函数注册到Model中。
      

        public class IController
        {
            ComModel comModel = new ComModel();
            IView view;
    
            public IController(IView view)
            {
                this.view = view;
                view.SetController(this);
                //将页面上的更新界面函数注册到Model的事件
                comModel.comCloseEvent += new SerialPortEventHandler(view.CloseComEvent);
                comModel.comOpenEvent += new SerialPortEventHandler(view.OpenComEvent);
                comModel.comReceiveDataEvent += new SerialPortEventHandler(view.ComReceiveDataEvent);
            }
        }

    一般来说Controller比较复杂的一部分,但在这个程序中比较简单,没有数据库相关的操作。

      

    在界面层

      声明一个接口  IView,并在mainform中引用这个接口   “public partial class FormMain : Form,IView

      public interface IView
      { 

      void ComReceiveDataEvent(Object sender, SerialPortEventArgs e);

      }

    编写串口接收事件函数

    public void ComReceiveDataEvent(object sender, SerialPortEventArgs e)
    {

              //
              // 摘要:
              //     获取一个值,该值指示调用方在对控件进行方法调用时是否必须调用 Invoke 方法,因为调用方位于创建控件所在的线程以外的线程中。
              //
              // 返回结果:
              //     如果控件的 System.Windows.Forms.Control.Handle 是在与调用线程不同的线程上创建的(说明您必须通过 Invoke 方法对控件进行调用),则为
              //     true;否则为 false。
                if (this.InvokeRequired)
                {
                    try
                    { //
                      // 摘要:
                      //     在拥有控件的基础窗口句柄的线程上,用指定的参数列表执行指定委托。
                      //
                      // 参数:
                      //   method:
                      //     一个方法委托,它采用的参数的数量和类型与 args 参数中所包含的相同。
                      //
                      //   args:
                      //     作为指定方法的参数传递的对象数组。如果此方法没有参数,该参数可以是 null。
                      //
                      // 返回结果:
                      //     System.Object,它包含正被调用的委托返回值;如果该委托没有返回值,则为 null。
                        Invoke(new Action<Object, SerialPortEventArgs>(ComReceiveDataEvent), sender, e);
                    }
                    catch (System.Exception)
                    {
                        //disable form destroy exception
                    }
                    return;
                }
                if (true) //字符串display as string
                {
                    receivetbx.AppendText(Encoding.Default.GetString(e.receivedBytes));
                    receiveBytesCount += e.receivedBytes.Length;
                    acceptStatusLabel.Text = "Received: " + receiveBytesCount.ToString();
                }

    }

  • 相关阅读:
    【分布式锁】RedLock 实现分布式锁
    【反射】遍历对象属性名与值
    【ABP.Net】2.多数据库支持&&初始化数据库
    【ABP.Net】1.创建项目&介绍框架结构
    【Vue-Cli3.0】【2】渲染
    【nuget】PackageReference
    【Vue-Cli3.0】【1】创建一个Vue-Cli3.0的项目
    【干货】干货篇
    踩坑记录-Redis(Windows)的getshell
    极致CMS存储XSS|前台打后台COOKIE漏洞复现
  • 原文地址:https://www.cnblogs.com/12xiaole/p/8275127.html
Copyright © 2020-2023  润新知