DAY-0429 多线程操作

由于需要使用一个线程来执行对远端设备的实时读取,

1.线程何时启动,目前在每次按下实时读取按钮后创建一个新线程,用于实时读取

2.多线程在关闭再次启动后报错:多线程在每次读取数据按钮click时都需要重新开启,线程的停止使用while中判断isReadPlc还是使用直接Abort,目前未使用Abort,且不用Abort比较安全(不太懂)。

3.跨线程访问报错,方法1:System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;  此方法无法保证线程安全,故更换方案

我们需要使用invoke

首先了解几个概念  同步:调用者需要等待方法调用返回后才能进行下一步工作  异步:调用者可以继续下一步操作,异步方法通常会在另一个线程执行。

阻塞和非阻塞 强调的是程序在等待调用结果(消息,返回值)时的状态.  阻塞调用是指调用结果返回之前,当前线程会被挂起。调用线程只有在得到结果之后才会返回。非阻塞调用指在不能立刻得到结果之前,该调用不会阻塞当前线程。 对于同步调用来说,很多时候当前线程还是激活的状态,只是从逻辑上当前函数没有返回而已,即同步等待时什么都不干,白白占用着资源。

     private void constantRW_Click(object sender, EventArgs e)//开始多线程读取
        {
            //关闭连线按钮
            constantRW.Enabled = false;
            //打开断线按钮
            stop_ConstantRead.Enabled = true;
            //读取旗标
            isReadPlc = true;
            //创建新线程
            threadRead = new Thread(ThreadReadRobot);
            //将线程设定为后台线程
            threadRead.IsBackground = true;
            //启动该线程,执行方法ThreadReadRobot到最后多线程会在GC中销毁
            threadRead.Start();

        }
        private void threadReadFun()
        {
            textBox17.Text = textBox17.Text + DELTARobotClient.ReadFloat("1").Content;
        }
        private void stop_ConstantRead_Click(object sender, EventArgs e)//停止多线程读取
        {
            //打开连线按钮
            constantRW.Enabled = true;
            //关闭断线按钮
            stop_ConstantRead.Enabled = false;
            //读取旗标
            isReadPlc = false;
            //停止多线程
            threadRead?.Abort();
        }
        private void ThreadReadRobot()//多线程读取方法
        {
            while (isReadPlc)
            {
                Thread.Sleep(timeSleep);
                if(isReadPlc)
                {
                    this.Invoke(new Action(() =>
                    {
                        threadReadFun();
                    }));
                }
            }
        }

实时读取(多线程中的界面更新,需要将涉及界面的代码封装为方法,通过Invoke或者BeginInvoke 调用,减轻UI线程工作量)
多线程1:目前在每次按下实时读取按钮constantRW_Click后创建一个新线程(后台线程),该线程用于实时读取。按下停止按钮stop_ConstantRead_Click后将多线程读取标志位写false,并且关闭线程。
2:添加一个界面更新的代码方法threadReadFun,该方法在后台线程方法ThreadReadRobot中调用,由于是跨线程调用,故使用invoke方式

posted @ 2020-05-05 23:44  xiaoyaay  阅读(166)  评论(0编辑  收藏  举报