WPF TCP传输主界面卡死假死问题

之前做过一个winform的TCP通讯的程序,只要在load函数加一句CheckForIllegalCrossThreadCalls = false;即可。但是到了wpf里面这句话没了,查阅了很多资料,把我所理解的wpf多线程分享一下

大部分人百度,查出来的都是这么一个答案:

private void ReciveMsg(object o)//接收函数
        {
         this.Dispatcher.Invoke(new Action(delegate
            {
                try
                {
                client = o as Socket;
                //创建缓存内存,存储接收的信息   ,不能放到while中,这块内存可以循环利用
                byte[] arrlist = new byte[1024 * 1024];
                while (true)
                {
                     //TCP接收代码,核心是下面这一句
                    int length = client.Receive(arrlist);
                    if (length <= 0)
                    {
                        return;
                    }
                    string receive = Encoding.UTF8.GetString(arrlist, 0, length);
                    
                   //TCP接收到的数据放在控件上的代码,因人而异不写了
                   
                }
                catch (Exception ex)
                {
                    
                }
            }));
            }

这种函数如果是秒收到的TCP数据还是可以的,直到我遇到了一个需要等待40s才收到的TCP通讯,client.Receive(arrlist)这句一直卡了40s直到收到数据才能动,一开始想的是设置超时时间,即:

client.SendTimeout = 2000;
client.ReceiveTimeout = 2000;

这样过了2s中还没收到数据程序就不卡死了,但是收不到想要的数据了,并不能解决核心程序假死问题。后来百度了一下午,有点懂得WPF多线程的使用:

WPF其实就只有一个UI主线程,如果代码里要调用UI里面的控件,就要把函数放在:

this.Dispatcher.Invoke(new Action(delegate
            {
            }));

中即可,如果其他需要等待的函数和UI主线程放一起,就会造成主界面的假死!所以TCP接收的函数,不能和UI线程的函数放一起!

所以换一种思路,先设置一个全局变量在外面,TCP接收的时候赋值给这个变量,然后把UI线程的函数放在一个Timer里面,每隔1ms检测一下是否收到了TCP的数据,下面给一下简单实现的代码:

  //自定义全局变量
  string receive_TCP_Data = "";
  string receive_TCP_Data_Compare = "";
  //初始化timer
  DispatcherTimer timer = new DispatcherTimer();
       
  private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            //timer
            timer.Tick += new EventHandler(timer_Tick);
            //设置刷新的间隔时间
            timer.Interval = TimeSpan.FromSeconds(0.001);
            timer.Start();
        }

 private void timer_Tick(object sender, EventArgs e)
        {
            this.Dispatcher.Invoke(new Action(delegate
            {
              

                try
                {
                    //比较收到的数据是否和之前一样
                    if (receive_TCP_Data != receive_TCP_Data_Compare )
                    {
                        receive_TCP_Data_Compare = receive_TCP_Data;

                        //下面是控件的具体操作,因人而异
                        Class_DataGrid_UpdataResult dg = new Class_DataGrid_UpdataResult(
                            id++,
                            string.Format("[{0:yyyy-MM-dd HH:mm:ss fff}]", DateTime.Now),
                            "TCP接收:" + receive_TCP_Data
                            );
                        DataGrid_UpdataResult.Items.Add(dg);
                        DataGrid_UpdataResult.ScrollIntoView(dg);




                    }

                }
                catch (Exception ex)
                {
                    
                }


            }));
        }

private void ReciveMsg(object o)//接收
        {
            try
            {
                client = o as Socket;
                //创建缓存内存,存储接收的信息   ,不能放到while中,这块内存可以循环利用
                byte[] arrlist = new byte[1024 * 1024];
                while (true)
                {
                    
                    int length = client.Receive(arrlist);
                    if (length <= 0)
                    {
                        return;
                    }
                    string receive = Encoding.UTF8.GetString(arrlist, 0, length);
                    //给全局变量赋值
                    receive_TCP_Data = receive ;
                   
                }
            }
            catch (Exception ex)
            {
                //MessageBox.Show("ReciveMsg" + ex.Message);
            }

            


        }
        
        //TCP建立通讯和发送的就不写了,百度搜搜一堆
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值