C#使用委托在Socket Udp端口侦听线程内更新主窗口控件显示

c#开启线程侦听Socket UDP端口,端口接收到网络读卡器的读卡数据后刷新UI界面显示接收数据,解析数据包信息并向读卡器发送显示文字、驱动读卡器播报语音、蜂鸣响声提示、开启继电器开关等操作。

本示例使用设备介绍:

1、刷卡后将卡号、机号等信息通过UDP协议上传到指定的远程服务器IP、端口

2、接收并响应远程服务器发送过来的显示文字、蜂鸣响声、TTS中文语音播报、开关继电器等指令。

WIFI无线网络RFID云读卡器远程网络开关物流网NB-IoT4G刷卡阅读器-淘宝网 (taobao.com)

   .net 提示通过设置:CheckForIllegalCrossThreadCalls = false,可以在子线程内强制更新主窗口内控件值来刷新UI显示,但是这样使用有时会出现显示信息刷新不及时、造成显示卡顿、或软件直接奔溃等问题,有资料显示微软并不推荐使用这种子线程内强制刷新UI显示的,强烈建议使用委托的方式来刷新UI显示,代码如下:

定义好委托及传送参数:

delegate void Update1(string text1, byte[] bytes, int byteslen);   //UDP端口侦听线程内解析接收到的数据并更新UI委拖
delegate void Update2(string text1, string msg);                   //UDP端口侦听线程内更新UI委拖
复制代码

开启Socket Udp侦听端口并启动侦听线程:

        private void StartListener()
        {
            IPEndPoint LocalPoint;
            PortNumber = Convert.ToInt32(textBox23.Text);
            while (!ready)
            {
                try
                {
                    LocalPoint = new IPEndPoint(IPAddress.Parse(localIp), PortNumber);
                    ListenerSock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
                    ListenerSock.Bind(LocalPoint);

                    ListenerThre = new Thread(new ThreadStart(ThrListener));
                    ListenerThre.Start();
                    ready = true;
                }
                catch
                {
                    ListenerSock.Close();
                    ready = false;
                    MessageBox.Show("有其它应用程序占用了 " + PortNumber.ToString() + " ,请检查并关闭此应用后再打开本程序", "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    System.Environment.Exit(0);                      //这是最彻底的退出方式,不管什么线程都被强制退出,把程序结束的很干净。
                }
            }
        }

        public void ThrListener()
        {
            while (ready)
            {
                try
                {
                    EndPoint RemotePoint = new IPEndPoint(System.Net.IPAddress.Any, 0);
                    byte[] bytes = new byte[1024];
                    int NumGet = ListenerSock.ReceiveFrom(bytes, ref RemotePoint);
                    RemoteIPoint = (IPEndPoint)RemotePoint;                                 //获取数据包来源IP及端口,原路回应

                    string dispstr = DateTime.Now.ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss") + (" FromIP:" + Convert.ToString(RemotePoint) + "          ").Substring(0, 30) + "Data:";
                    this.BeginInvoke(new Update1(EditUi1), dispstr, bytes, NumGet);        //通过委托传送参数显示接收到的数据包,并根据情况回应设备            
                }
                catch (Exception ex)
                {
                    this.BeginInvoke(new Update2(EditUi2), DateTime.Now.ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss") + " ", ex.Message);   //通过委托传送参数显示接收到的数据            
                }
            }
        }
复制代码

委托更新UI显示

private void EditUi1(string text1, byte[] buf, int buflen)     //通过委托更新UI,数组传送参数
{            
            int i;
            string recestr = "";//接收数据显示

            for (i = 0; i < buflen; i++)
            {
                recestr = recestr + buf[i].ToString("X2") + " ";
            }
            
            ListItemAdd(text1 + recestr);
            
}
         
private void EditUi2(string text1, string Msg)     //通过委托更新UI,字符串传送参数
{
     ListItemAdd(text1 + Msg);
}

猜你喜欢

转载自blog.csdn.net/zhangjin7422/article/details/129101522