当前位置: 移动技术网 > IT编程>开发语言>c# > c# Invoke和BeginInvoke 区别分析

c# Invoke和BeginInvoke 区别分析

2019年07月18日  | 移动技术网IT编程  | 我要评论

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

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

(一)control的invoke和begininvoke

我们要基于以下认识:
(1)control的invoke和begininvoke与delegate的invoke和begininvoke是不同的。
(2)control的invoke和begininvoke的参数为delegate,委托的方法是在control的线程上执行的,也就是我们平时所说的ui线程。

我们以代码(一)来看(control的invoke)

private delegate void invokedelegate();
private void invokemethod(){
//c代码段
}
private void butinvoke_click(object sender, eventargs e) {
//a代码段.......
this.invoke(new invokedelegate(invokemethod));
//b代码段......
}

你觉得代码的执行顺序是什么呢?记好control的invoke和begininvoke都执行在主线程即ui线程上
a------>c---------------->b
解释:(1)a在ui线程上执行完后,开始invoke,invoke是同步
(2)代码段b并不执行,而是立即在ui线程上执行invokemethod方法,即代码段c。
(3)invokemethod方法执行完后,代码段c才在ui线程上继续执行。

看看代码(二),control的begininvoke

private delegate void begininvokedelegate();
private void begininvokemethod(){
//c代码段
}
private void butbegininvoke_click(object sender, eventargs e) {
//a代码段.......
this.begininvoke(new begininvokedelegate(begininvokemethod));
//b代码段......
}

你觉得代码的执行顺序是什么呢?记好control的invoke和begininvoke都执行在主线程即ui线程上
a----------->b--------------->c慎重,这个只做参考。。。。。,我也不肯定执行顺序,如果有哪位达人知道的话请告知。

解释::(1)a在ui线程上执行完后,开始begininvoke,begininvoke是异步

(2)invokemethod方法,即代码段c不会执行,而是立即在ui线程上执行代码段b。
(3)代码段b执行完后(就是说butbegininvoke_click方法执行完后),invokemethod方法,即代码段c才在ui线程上继续执行。

由此,我们知道:

control的invoke和begininvoke的委托方法是在主线程,即ui线程上执行的。也就是说如果你的委托方法用来取花费时间长的数据,然后更新界面什么的,千万别在ui线程上调用control.invoke和control.begininvoke,因为这些是依然阻塞ui线程的,造成界面的假死。

那么,这个异步到底是什么意思呢?

异步是指相对于调用begininvoke的线程异步,而不是相对于ui线程异步,你在ui线程上调用begininvoke ,当然不行了。----摘自"invoke和begininvoke的真正涵义"一文中的评论。
begininvoke的原理是将调用的方法marshal成消息,然后调用win32 api中的registerwindowmessage()向ui窗口发送消息。----摘自"invoke和begininvoke的真正涵义"一文中的评论。

(二)我们用thread来调用begininvoke和invoke

我们开一个线程,让线程执行一些耗费时间的操作,然后再用control.invoke和control.begininvoke回到用户ui线程,执行界面更新。

代码(三) thread调用control的invoke

private thread invokethread;
private delegate void invokedelegate();
private void startmethod(){
//c代码段......
control.invoke(new invokedelegate(invokemethod));
//d代码段......
}
private void invokemethod(){
//e代码段
}
private void butinvoke_click(object sender, eventargs e) {
//a代码段.......
invokethread = new thread(new threadstart(startmethod));
invokethread.start();
//b代码段......
}


你觉得代码的执行顺序是什么呢?记好control的invoke和begininvoke都执行在主线程即ui线程上
a------>(start一开始b和startmethod的c就同时执行)---->(c执行完了,不管b有没有执行完,invokethread把消息封送(invoke)给ui线程,然后自己等待)---->ui线程处理完butinvoke_click消息后,处理invokethread封送过来的消息,执行invokemethod方法,即代码段e,处理往后ui线程切换到invokethread线程。

这个control.invoke是相对于invokethread线程同步的,阻止了其运行。


解释:

1。ui执行a
2。ui开线程invokethread,b和c同时执行,b执行在线程ui上,c执行在线程invokethread上。
3。invokethread封送消息给ui,然后自己等待,ui处理完消息后,处理invokethread封送的消息,即代码段e
4。ui执行完e后,转到线程invokethread上,invokethread线程执行代码段d

代码(四) thread调用control的begininvoke

private thread begininvokethread;
private delegate void begininvokedelegate();
private void startmethod(){
//c代码段......
control.begininvoke(new begininvokedelegate(begininvokemethod));
//d代码段......
}
private void begininvokemethod(){
//e代码段
}
private void butbegininvoke_click(object sender, eventargs e) {
//a代码段.......
begininvokethread = new thread(new threadstart(startmethod));
begininvokethread .start();
//b代码段......
}


你觉得代码的执行顺序是什么呢?记好control的invoke和begininvoke都执行在主线程即ui线程上
a在ui线程上执行----->begininvokethread线程开始执行,ui继续执行代码段b,并发地invokethread执行代码段c-------------->不管ui有没有执行完代码段b,这时begininvokethread线程把消息封送给ui,单自己并不等待,继续向下执行-------->ui处理完butbegininvoke_click消息后,处理begininvokethread线程封送过来的消息。



解释:

1。ui执行a
2。ui开线程begininvokethread,b和c同时执行,b执行在线程ui上,c执行在线程begininvokethread上。
3。begininvokethread封送消息给ui,然后自己继续执行代码d,ui处理完消息后,处理invokethread封送的消息,即代码段e
有点疑问:如果ui先执行完毕,是不是有可能过了段时间begininvokethread才把消息封送给ui,然后ui才继续执行封送的消息e。如图浅绿的部分。

control的begininvoke是相对于调用它的线程,即begininvokethread相对是异步的。
因此,我们可以想到。如果要异步取耗费长时间的数据,比如从数据库中读大量数据,我们应该这么做。
(1)如果你想阻止调用线程,那么调用代码(三),代码段d删掉,c改为耗费长时间的操作,因为这个操作是在另外一个线程中做的。代码段e改为更新界面的方法。
(2)如果你不想阻止调用线程,那么调用代码(四),代码段d删掉,c改为耗费长时间的操作,因为这个操作是在另外一个线程中做的。代码段e改为更新界面的方法。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网