关于c# 主线程子线程用法规范, 以及子线程更新ui那些事和安卓对比是怎么样的呢...

博客探讨了在Android和C#中处理UI线程与子线程交互的方法,强调了避免主线程执行耗时操作的重要性。通过示例代码展示了如何在Android中使用Looper和在C#中使用Invoke来更新UI,并提供了判断当前线程的技巧。此外,还介绍了在多线程环境下读取和更新UI的最佳实践。
摘要由CSDN通过智能技术生成

最近同事的一系列操作,惊掉了我的下巴,和那时候的我很像,我那时候玩易语言也不知道耗时操作应该怎么优化体验,应该怎么写,什么才是规范,
直到遇到安卓,安卓强制不让在主线程写耗时代码,我才慢慢的进入了规范。
安卓要想在子线程更新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.htmlhttp://www.javashuo.com/article/p-fqopwglf-hx.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值