• 异步调用误区


    最近在优化代码的时候发现了一些问题,多是开启异步线程出现的一些问题,具体就是某个耗时操作的结果需要更新界面控件的值。

    大概的方法就是利用Control.Invoke(delegate())这样的方法去解决跨控件访问问题,但问题也出在这里了

            void SendEditedNepImage1(bool obj)
            {
                if (this.InvokeRequired)
                {
                    this.Invoke((Action)delegate()
                    {
                        SendEditedNepImageImp1(obj);
                    });
                }
                else
                {
                    SendEditedNepImageImp1(obj);
                }
            }
            void SendEditedNepImageImp1(bool obj)
            {
                for (int i = 0; i < 1000000; i++)
                {
                    if (i == 1000000 - 1)
                    {
                        label1.Text = i.ToString();
                    }
                }
            }

    这样的办法看上去是解决了跨线程访问控件的问题了,有人会说你可以用BeginInvoke 加委托的方式啊,但事实真的如此吗?

    让我们先来看看BeginInvoke 和Invoke的具体含义吧:

    Control.Invoke 方法 (Delegate) :在拥有此控件的基础窗口句柄的线程上执行指定的委托。

    Control.BeginInvoke 方法 (Delegate) :在创建控件的基础句柄所在线程上异步执行指定委托。

    按照这个定义去理解,只要是主线程创建的控件,你想用异步线程去操作它,最终又回到了创建它的线程,也就是UI线程,因为我的label就是主线程创建的,可能BeginInvoke会好些,它是异步的,但是也是在主线程下,对于即时性强的程序来说还是不可取,要不我们来解决它吧,这是我自己摸索的办法,也不知道靠不靠谱,我来改改吧,这样子改至少界面不卡了。

            void Relute()
            {
                string ss = string.Empty;
                for (int i = 0; i < 1000000000; i++)
                {
                    if (i == 1000000000 - 1)
                    {
                        ss = i.ToString();
                    }
                }
                if (this.InvokeRequired)
                {
                    this.Invoke((Action)delegate()
                    {
                        label1.Text = ss;
                    });
                }
                else
                {
                    label1.Text = ss;
                }
    
            }
    
            /// <summary>
            /// 模拟图片发送
            /// </summary>
            /// <param name="obj"></param>
            void SendEditedNepImageImp(bool obj)
            {
                Thread th = new Thread(() => Relute());
                th.Start();
            }

    好了不多说了,很简单的东西,看了就明白了。

  • 相关阅读:
    五月杂题选做
    BJOI 2021 游记&题解
    U149858
    CF1037简要题解
    CF Round706简要题解
    联合省选 2020
    九省联考 2018 IIIDX
    九省联考 2018 秘密袭击
    AGC006F Balckout
    概率生成函数学习笔记
  • 原文地址:https://www.cnblogs.com/ouzining/p/4209030.html
Copyright © 2020-2023  润新知