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);
}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

vx_13822155058

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值