C# BeginInvoke / Invoke
1.Control下调用
1.1 在主线程调用
listBox1.Items.Add("--begin--");listBox1.Invoke(new Action(() =>{listBox1.Items.Add("Invoke");}));Thread.Sleep(1000);listBox1.Items.Add("--end--");
listBox1.Items.Add("--begin--");var bi = listBox1.BeginInvoke(new Action(() =>{//Thread.Sleep(10000);listBox1.Items.Add("BeginInvoke");}));Thread.Sleep(1000);listBox1.Items.Add("--end--");
此时两种情况都会卡死UI的
在主线程中直接调用Invoke、BeginInvoke、EndInvoke都会造成阻塞
1.2 在子线程调用
private void Button1_Click(object sender, EventArgs e){Thread.CurrentThread.Name = "Main";listBox1.Items.Add("--begin--");new Thread(() =>{Thread.CurrentThread.Name = "ThreadInvoke";string temp = "Before!";listBox1.Invoke(new Action(() =>{Thread.Sleep(10000);this.listBox1.Items.Add(temp += "Invoke!" + Thread.CurrentThread.Name);}));temp += "After!";}).Start();listBox1.Items.Add("--end--");}
1.listBox1.Invoke的委托其实也在主线程中执行
2.Invoke在支线程中调用也会阻塞主线程UI。
3.Invoke还会阻塞支线程。(因为输出结果中没有出现After)
private void Button1_Click(object sender, EventArgs e){Thread.CurrentThread.Name = "Main";listBox1.Items.Add("--begin--");new Thread(() =>{Thread.CurrentThread.Name = "ThreadBeginInvoke";string temp = "Before!";listBox1.BeginInvoke(new Action(() =>{Thread.Sleep(10000);this.listBox1.Items.Add(temp += "Invoke!" + Thread.CurrentThread.Name);}));temp += "After!";}).Start();listBox1.Items.Add("--end--");}
1.BeginInvoke在主线程中执行。
2.BeginInvoke在支线程中调用也会阻塞主线程。
3.BeginInvoke相对于支线程是异步的,即没有阻塞支线程
总结:
Control的Invoke和BeginInvoke的委托方法是在主线程,即UI线程上执行。(也就是说如果你的委托方法用来取花费时间长的数据,然后更新界面什么的,千万别在主线程上调用Control.Invoke和Control.BeginInvoke,因为这些是依然阻塞UI线程的,造成界面的假死)
Invoke会阻塞主支线程,BeginInvoke只会阻塞主线程,不会阻塞支线程!因此BeginInvoke的异步执行是指相对于支线程异步,而不是相对于主线程异步。
2.Delegate调用
delegate void xDel(int i);private void Button1_Click(object sender, EventArgs e){Thread.CurrentThread.Name = "Main";listBox1.Items.Add("--begin--");xDel xd = new xDel(t =>{//Thread.Sleep(t);//listBox1.BeginInvoke(new Action(() =>//{// listBox1.Items.Add("Invoke");//}));Thread.CurrentThread.Name = "ThreadBeginInvoke";string temp = "Before!";listBox1.BeginInvoke(new Action(() =>{Thread.Sleep(10000);this.listBox1.Items.Add(temp += "Invoke!" + Thread.CurrentThread.Name);}));temp += "After!";});xd.BeginInvoke(3000, null, null);listBox1.Items.Add("--end--");}
其实这种情况跟上面new Thread是一样的,委托的beginInvoke也是开了一个线程
注:
在WPF中,写法又有点不一样,要Dispatcher.Invoke
listBox1.Items.Add("--begin--");listBox1.Dispatcher.Invoke(new Action(() =>{listBox1.Items.Add("Invoke");}));Thread.Sleep(1000);listBox1.Items.Add("--end--");
参考:
https://www.cnblogs.com/wangshenhe/archive/2012/05/25/2516842.html
https://www.cnblogs.com/small-code/p/5732116.html
https://blog.csdn.net/goodshot/article/details/6157529
https://www.cnblogs.com/c2303191/articles/826571.html
https://blog.csdn.net/sinat_23338865/article/details/52596818
https://www.cnblogs.com/djzxjblogs/p/7525206.html
C# BeginInvoke / Invoke相关推荐
- (转)Invoke and BeginInvoke
Invoke and BeginInvoke 在Invoke或者BeginInvoke的使用中无一例外地使用了委托Delegate,至于委托的本质请参考我的另一随笔:对.net事件的看法. 一.为什么 ...
- 为什么Control类提供了Invoke和BeginInvoke机制
在Invoke或者BeginInvoke的使用中无一例外地使用了委托Delegate,至于委托的本质请参考我的另一随笔:对.net事件的看法. 一.为什么Control类提供了Invoke和Begin ...
- 委托的Invoke 和 BeginInvoke 与Control的Invoke和BeginInvoke(转-因为写得很好)
原文地址:http://www.cnblogs.com/worldreason/archive/2008/06/09/1216127.html Invoke and BeginInvoke Invok ...
- 【分析】浅谈C#中Control的Invoke与BeginInvoke在主副线程中的执行顺序和区别(SamWang)
今天无意中看到有关Invoke和BeginInvoke的一些资料,不太清楚它们之间的区别.所以花了点时间研究了下. 据msdn中介绍,它们最大的区别就是BeginInvoke属于异步执行的. Cont ...
- Invoke and BeginInvoke BeginInvoke和EndInvoke方法 (转)2
七.其他组件的BeginXXX和EndXXX方法 在其他的.net组件中也有类似BeginInvoke和EndInvoke的方法,如System.Net.HttpWebRequest类的BeginGe ...
- C#中的Invoke和BeginInvoke
一.Control#Invoke() 和Control#BeginInvoke() 在非UI线程中调用MessageBox.Show()结果是非模态对话框: 在UI线程中调用MessageBox.Sh ...
- C# Invoke和BeginInvoke(1)
近日,被Control的Invoke和BeginInvoke搞的头大,就查了些相关的资料,整理如下.感谢这篇文章对我的理解Invoke和BeginInvoke的真正含义 . (一)Control的In ...
- C#中invoke和beginInvoke
C#中invoke和beginInvoke invoke的含义是:在拥有此控件的基础窗口句柄的现呈上同步执行指定的委托(同步) beginInvoke的含义是:在创建控件的基础句柄所在线程上异步执行的 ...
- c# Invoke 与BeginInvoke 的用法
最近在学习线程时,发现当我创建的线程需要访问UI界面的时,会发生异常,原因是我在跨线程调用主线程的控件,因此windows GUI编程有一个规则,就是只能通过创建控件的线程来操作控件的数据,否则就可能 ...
最新文章
- python序列类型包括哪三种映射类型_python序列类型包括哪三种_后端开发
- Taurus.MVC 2.0 开源发布:WebAPI开发教程
- 【php】目录操作 文件操作
- 【Tomcat】Tomcat 系统架构与设计模式,第 1 部分: 工作原理
- android4.0 开机启动activity 4.0,如何正确理解和使用Activity的4种启动模式
- kafka集群为什么需要三个节点_大白话带你认识 Kafka
- 数据结构课程设计 迷宫问题
- oracle 删除行记录,使用实体框架从oracle数据库中删除记录
- python一对一教学质量怎么样_Python大牛开小灶,一对一问答
- APP功能测试点汇总
- 基恩士plc-EtherCAT三十一轴,控制案例程序(包含plc程序/人机界面/BOM表)
- 如何制作gif动态图片
- 计算机术语 gc 是什么意思,GC是什么?为什么我们要去使用它
- 称重管理系统服务器不通,称重管理系统使用方法(二)
- 跨国族群布里亚特的特殊“年味儿”
- OWT在企业远程智能视频服务场景中的应用
- 「YGG Japan」宣布已完成约 295 万美元的新股权私募
- ONNX Runtime: ubutnu16.04编译 (编到怀疑人生)
- SwiftUI 精品项目之完整MOOC幕课iOS项目 含服务端 轮播欢迎页面(教程含源码)
- 杰理之PAP接口【篇】