Winform 关于委托与Invoke和Begin Invoke的使用
这方面的文章已经写得很详细了,特地摘引两篇文章
http://www.cnblogs.com/c2303191/articles/826571.html
http://www.cnblogs.com/EasonLeung/p/3683492.html
http://www.cnblogs.com/Rustle/articles/11301.aspx
然后我想把自己的理解记录下来,做一个笔记。
1.Control的Invoke和BeginInvoke的委托方法是在主线程,即UI线程上执行的,异步是指相对于调用BeginInvoke的线程异步,而不是相对于UI线程异步,BeginInvoke的原理是将调用的方法Marshal成消息,然后调用Win32 API中的RegisterWindowMessage()向UI窗口发送消息
2.委托的执行过程类似于线程的执行(实际上本质就是线程),当委托被Invoke以后,程序会开启一个异步线程执行委托,当委托执行完毕时线程自动终止
3.Invoke 和 BeginInvoke 就是为了解决在多线程中安全的更新界面显示而出现的。
将工作线程中涉及更新界面的代码封装为一个方法,通过 Invoke 或者 BeginInvoke 去调用,两者的区别就是一个导致工作线程等待,而另外一个则不会(工作线程即UI线程)
4.在新的线程中使用Invoke和BeginInvoke这种方式,其调用的委托其实相当于“注入”到了主控制线程中,它取得了主线程的控制
5.主线程表示Control.Invoke或Control.BeginInvoke中Control所在的线程,即创建该Control的线程。(一般为UI线程)
支线程表示调用Invoke或BeginInvoke的线程。
- Invoke、BeginInvoke始终在主线程中执行。
- Invoke被调用时就会直接执行,也就是直接阻塞线程(包括主支线程),直到它结束。而BeginInvoke只有等支线程结束或者调用EndInvoke、Invoke时才会开始执行。
- Invoke不管在哪里执行都会造成主线程的阻塞。而BeginInvoke只会阻塞支线程,而对于主线程是异步执行。(注意,如果在主线程中调用,也会阻塞主线程)。
- 在支线程中,应该使用BeginInvoke,否则调用Invoke将导致支线程阻塞主线程,该支线程就没有存在的意义。(当然有特殊需求除外)。