代理在处理C#串行端口响应时不起作用

时间:2019-07-10 14:07:45

标签: c# serial-port

我有一个简单的.NET C#应用程序,可与USB设备通信。如果通信成功,则DataReceivedHandler“应该”获取设备响应(port.ReadExisting)并更新UI-一个简单的asp:label控件。

我知道UI更新确实发生在不同的线程上,因此必须使用委托来调用更新函数。我尝试了几种不同的解决方案,但未能使其正常工作。我可以确认计算机与设备之间的通信是否成功。

代码如下:

using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Text;

namespace SerialPortCommunication
{
    public delegate void UpdateLogDelegate(string msg);

    public partial class button : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
        }

        public void UpdateLog(string msg)
        {
            lblLog.Text = msg;
        }

        protected void Button1_Click(object sender, EventArgs e)
        {
            var request = new byte[] { 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 }

            SerialPort port = new SerialPort("COM8");

            port.BaudRate = 19200;
            port.Parity = Parity.Even;
            port.StopBits = StopBits.One;
            port.DataBits = 7;

            port.Open();

            port.Write(request, 0, request.Length);
            port.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
        }

        public void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
        {
            SerialPort port = (SerialPort)sender;
            string incomingData = port.ReadExisting();

            UpdateLogDelegate log = new 
            UpdateLogDelegate(UpdateLog);
            log.Invoke(incomingData);

            port.Close();
        }
    }
}

先谢谢您。 :)

1 个答案:

答案 0 :(得分:0)

我认为您不太理解代表们。这个想法是您创建一个委托,然后创建该委托的实例并为其分配功能。因此,在您的DataReceived事件中,它将始终调用其设置为的函数。您正在创建一个新实例,但未正确为其分配功能。请在下面查看我的修复程序:

using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Text;

namespace SerialPortCommunication
{
    public delegate void UpdateLogDelegate(string msg);
    public UpdateLogDelegate ULD;   //create instance of your delegate that you will assign a function to

    public partial class button : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
        }

        public void UpdateLog(string msg)
        {
            //the serial port datareceived event is on a different thread
            //you'll have to invoke to update your GUI
            this.Invoke((MethodInvoker)delegate
            {
                lblLog.Text = msg;
            });
        }

        protected void Button1_Click(object sender, EventArgs e)
        {
            var request = new byte[] { 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 }

            SerialPort port = new SerialPort("COM8");

            port.BaudRate = 19200;
            port.Parity = Parity.Even;
            port.StopBits = StopBits.One;
            port.DataBits = 7;
            port.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);   //move this before you write to the port

            //initialize your delegate to the UpdateLog function
            //but note, maybe if you had a Button2_click you could set ULD to a different
            //function and as data came in it would just call the correct function
            ULD = UpdateLog;    

            port.Open();

            port.Write(request, 0, request.Length);
        }

        public void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
        {
            //your port is already global so you dont need to re-declare it
            string incomingData = port.ReadExisting();

            ULD(incomingData);

            port.Close();   //I wouldn't close the port here, but for testing this is ok
        }
    }
}