• 在C#的涉及UI的开发中,跨线程直接访问控件的解决方案


    解决方案:
      
    通过委托的方式,实现将当前线程的将要执行的命令,插入到访问控件的线程中.
       经典的解释:
         
    你想要买东西,然而你没有足够的零花钱(没有足够的权限),你需要通过你老爸帮你买东西(执行功能代码)。
          你不能直接拿你老爸的钱包去买东西(跨线程),因为这样子是不合适的。
          但你可以告诉你老爸你喜欢这玩具(委托),让你老爸拿自己的钱包去买东西(让控件的所在线程执行功能代码)。

    实现过程:
    a.创建委托函数delegate void MyDele(...);
    b.将要执行的功能代码封装成独立函数或Lambda表达式或者匿名方法,添加到委托事件中。
        独立函数:
            MyDele my = new MyDele(独立函数名);
            
        Lambda表达式:
            MyDele my =(传参)=>{要执行的功能代码;};

        匿名方法:
            MyDele my = delegate(传参){要执行的功能代码;};

    c.将委托插入到访问控件的线程中。
        this.BeginInvoke(委托事件名,传参);

    WinForm的UI开发:

       可以通过control.InvokeRequired判断该控件是属于本线程,如果不属于本线程,则返回ture。
       通过在函数头对control.InvokeRequired的判断,能够将所在函数作为独立函数调用。
    void TestFunction(...)
    {
        if(control.InvokeRequired)
        {
            MyDele my  = new MyDele(TestFunction);
            this.BeginInvoke(my,...);
            return;    
        }

        要执行的功能代码;    
    }
       在跨线程调用控件时,会创建委托事件,将该函数添加到委托事件中,插入到访问控件的线程中,并且退出该函数。
       当所访问控件的线程执行到该委托事件时,由于该控件是在本线程执行。因此,不会创建委托事件,从而执行功能代码。

    MFC的UI开发:
       MFC的Invoke相关的API是存在control.Dispatcher中,但不存在InvokeRequired这API。
       由于不存在InvokeRequired这API,因此无法判断是否跨线程调用控件。
       不能够将所在的函数作为独立函数调用(如上述的实现方式)。
       只能通过常规的实现方式实现:
    void TestFunction(...)
    {
        // a.独立函数: 
        MyDele my = new MyDele(独立函数名);
            
        // b.Lambda表达式:
        MyDele my =(传参)=>{要执行的功能代码;};

        //c.匿名方法:
        MyDele my = delegate(传参){要执行的功能代码;};

        this.Dispatcher.BeginInvoke(my,传参);
    }
       通过将要执行的功能代码/函数,添加到委托事件中,再将该委托事件插入到控件所在的线程,让控件所在的线程执行该功能代码/函数。

    转载请备注:
    **************************************
    * 作者: Wurq 
    * 博客: http://www.cppblog.com/wurq/ 
    * 日期: 2017/8/16 
    **************************************
  • 相关阅读:
    解决Qt5 Creator无法切换输入法(fcitx),不能录入汉字问题
    QProcess进程间双向通信
    DB2使用存储过程插入数据
    Qt自定义圆周动画(360 10.0 的模仿作者写的)
    经典重温:给微软上课的快乐车夫
    很劲爆!紫光赵伟国在北京微电子会议上12条惊人语录
    中芯国际董事长周子学:技术终有山顶,我们用时间换技术
    windows完全支持C++11的轻量级编译器(官网MinGW和非官方的MinGW-builds)
    VMwarevSphere 服务器虚拟化之二十九 桌面虚拟化之安装View副本服务器
    Qt判断和打开进程(windows端),运行,检测,中止
  • 原文地址:https://www.cnblogs.com/Wurq/p/7383019.html
Copyright © 2020-2023  润新知