<2024年11月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

统计

  • 随笔 - 57
  • 文章 - 7
  • 评论 - 0
  • 引用 - 0

常用链接

留言簿

随笔分类

随笔档案

文章分类

文章档案

Blog

Coder 必备技巧

Compiler for Wurq

搜索

  •  

最新评论

阅读排行榜

评论排行榜

【技术干货】在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 
**************************************

posted on 2017-08-16 22:50 Wurq 阅读(165) 评论(0)  编辑 收藏 引用 所属分类: 【技术干货】


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理