美文网首页
关于c# 主线程子线程用法规范, 以及子线程更新ui那些事和安

关于c# 主线程子线程用法规范, 以及子线程更新ui那些事和安

作者: 吉凶以情迁 | 来源:发表于2022-06-09 15:09 被阅读0次

最近同事的一系列操作,惊掉了我的下巴,和那时候的我很像,我那时候玩易语言也不知道耗时操作应该怎么优化体验,应该怎么写,什么才是规范,
直到遇到安卓,安卓强制不让在主线程写耗时代码,我才慢慢的进入了规范。
安卓要想在子线程更新ui,就需要对Looper进行操作,但是这都是强制写法,实际上肯定不是这么用的,子线程就不应该这么用。。

安卓比较偷懒的写法:

任意ui控件.post();传递函数进去就实现函数体主线程执行

实际上c#也是类似

任意ui控件.Invoke(代理方法,参数)

,在安卓可以通过Thread.currentThread.Name()打印线程名,

在c#一样可以,但是默认为空,需要进行修改赋值才行。。

判断是否当前函数体代码在子线程运行的2种方法:

            if (this.textBox_log.InvokeRequired)//若是调用控件的线程和建立建立控件的线程不是同一个则为True
            {
                //if (Thread.CurrentThread.Name.Equals("子线程"))//这句话和上面等同this.textBox_log.InvokeRequire 

最后附属c#代码,改代码实现了 追加文本,不追加文本,
支持任意文本,标签控件改内容。也演示了如何判断是否在子线程的两种方法

完整代码


  /// <summary>
  /// 
  /// </summary>
  /// <param name="text">设置的内容</param>
  /// <param name="append">是否追加只有当第三个参数控件 不为空才有效果 </param>
  /// <param name="control"> 传递为空则修改textbox和label控件  textbox为追加 ,label为不追加</param>
        private void SetText(string text, bool? append = false, Control? control = null)
        {
            Debug.WriteLine(Thread.CurrentThread.Name + ":" + text + ",isappend:" + append);
            // InvokeRequired required compares the thread ID of the 
            // calling thread to the thread ID of the creating thread. 
            // If these threads are different, it returns true. 
            if (this.textBox_log.InvokeRequired)//若是调用控件的线程和建立建立控件的线程不是同一个则为True
            {
                //if (Thread.CurrentThread.Name.Equals("子线程"))//这句话和上面等同this.textBox_log.InvokeRequire 

                while (!this.textBox_log.IsHandleCreated)
                {
                    //解决窗体关闭时出现“访问已释放句柄“的异常
                    if (this.textBox_log.Disposing || this.textBox_log.IsDisposed)
                        return;
                }
                SetTextCallback callBack = new SetTextCallback(SetText);
                if (control != null)//如果不为空则代表修改指定控件
                {//这句话执行后还是调用当前方法,但是是在主线程运行的。 也就是走的else逻辑 ,  
                    this.label_status.Invoke(callBack, new object[] { text, append, control });
                }
                else
                {//如果没有传递control,则标签控件 为直接设置值,textbox控件则 追加值,  另外 ,这里的callback,
                 //不一定需要传递SetText,这里是偷懒复用当前方法参数,可以换成另外起一个主线程方法函数 也一样可以。
                    this.label_status.Invoke(callBack, new object[] { text, false, label_status });
                    this.textBox_log.Invoke(callBack, new object[] { text, true, textBox_log });

                }

            }
            else
            {//走主线程
            
                if (control != null)
                {
                    if (control is TextBox)
                    {
                        TextBox textBox = (control as TextBox);
                        if (append ?? false)
                        {
                            textBox.AppendText(text);
                        }
                        else
                        {
                            textBox.Text = text;

                        }
                    }
                    else
                    {
                        Label label = (control as Label);
                        if (append ?? false)
                        {
                            label.Text = label.Text + "\r\n" + text;
                        }
                        else
                        {
                            label.Text = text;

                        }
                    }
                }
                else
                {

                    this.textBox_log.Text = "[主线程调用]" + text;

                }

            }
        }




        // 第一步:定义委托类型
        // 将text更新的界面控件的委托类型
        delegate void SetTextCallback(string text, bool? append, Control? control);


        private void buttonreadresult_Click(object sender, EventArgs e)
        {

            Thread.CurrentThread.Name = "主线程";
            SetText("开始查询", false, label_status);
            if (loopRead)
            {
                SetText("当前已在运行,所以进行停止操作,当前已发送停止信号", false, label_status);
                loopRead = false;
                //MessageBox.Show("已停止");
                return;
            }
            else
            {
                loopRead = true;
            }




            int count = 30;
            int i = 0;


            new Thread(() =>
            {
                Thread.CurrentThread.Name = "子线程";

                SetText("[线程开始]", false, label_status);
                SetText("[线程开始]\n", false, textBox_log);


                while (loopRead)
                {


             

                    try
                    {
//这是业务代码,需要循环读取dll 方法。
                        ReadResult(ref pStatus, pSN1, pSN2, pIMEI1, pIMEI2, pIMEI3, pIMEI4, pMEID, pBT, pWIFI, pMBSN, pCURef, pAPSWVer, pSWVer, pNFC, pCCID, pMsgLine, pMSG, pGrid, pFailKind, ref pErrs);



                        Thread.Sleep(1000);



                        System.Diagnostics.Debug.WriteLine("ppStatus=>" + pCURef);
                        System.Diagnostics.Debug.WriteLine("pMsgLine=>" + pMsgLine.ToString());
                        System.Diagnostics.Debug.WriteLine("pMSG=>" + pMSG);
                        System.Diagnostics.Debug.WriteLine("pErrs=>" + pErrs);

                        SetText("\r\n状态" + pCURef + "\r\nMsgLine:" + pMsgLine + "\r\nMSG" + pMSG + "\r\nerr" + pErrs+ "\r\n", true,textBox_log);
                        i++;



                    }
                    catch (Exception e)
                    {
                        SetText("执行出现异常:"+e.ToString());
                        Console.WriteLine("ERROR " + e.ToString());
                        loopRead = false;
                        break;
                    }

                }
                System.Diagnostics.Debug.WriteLine("[线程结束]已退出查询");
                SetText("[线程结束]已退出查询",false,label_status);




            }).Start();






        }

参考

http://t.zoukankan.com/xingchen-p-2035083.html
http://www.javashuo.com/article/p-fqopwglf-hx.html

相关文章

  • 关于c# 主线程子线程用法规范, 以及子线程更新ui那些事和安

    最近同事的一系列操作,惊掉了我的下巴,和那时候的我很像,我那时候玩易语言也不知道耗时操作应该怎么优化体验,应该怎么...

  • Android 的线程和线程池

    Android 的线程分为主线程和子线程。 主线程更新 UI 子线程执行耗时操作 AsyncTask封装了线程池和...

  • Android Thread & AsyncTask & han

    《第一行代码》第十章笔记 线程用法 子线程中更新UI 如果想要更新应用程序里的UI元素, 则必须在主线程中进行, ...

  • 多线程系列第(八)篇---Android中的线程

    主线程和子线程 主线程,又叫UI线程,主要作用是运行四大组件以及处理它们和用户的交互。子线程也叫工程线程,主要作用...

  • 子线程更新UI的方法

    子线程中不能直接更新UI,如果直接更新的话会发生崩溃所以要在主线程中更新UI,总计三种回到主线程更新UI的方式 1...

  • Android进阶(11)| 线程和线程池

    一.主线程和子线程 主线程:主线程在Android中也叫做UI线程主线程的作用是运行四大组件以及处理它们与用户的交...

  • <> Chapter 11

    Android的线程和线程池 主线程和子线程 Android中的主线程也叫UI线程,主要作用是运行四大组件以及处理...

  • 关于Handler的简单理解

    handler主要用于线程的切换,因为在安卓中,主线程不能进行耗时操作,而子线程不能更新UI,所以当子线程网络请求...

  • AsyncTask原理分析

    AsyncTask在安卓中常用于线程间通信。在子线程执行耗时任务,在主线程更新UI。 AsyncTask内部封装了...

  • (十一)Android的线程和线程池

    11.1 主线程和子线程 Android主线程(UI线程)主要处理和界面相关得事情。主要运行四大组件以及处理它们和...

网友评论

      本文标题:关于c# 主线程子线程用法规范, 以及子线程更新ui那些事和安

      本文链接:https://www.haomeiwen.com/subject/kysmmrtx.html