C# invoke和beginInvoke
来源:互联网 发布:mac 中文乱码 编辑:程序博客网 时间:2024/06/05 04:48
UI线程以外的线程不能直接更新UI界面,那如何在工作线程中更新UI界面呢?
invoke和beginInvoke的出现是为了解决跨线程更新UI显示的问题,invoke是同步的执行,而beginInvoke是异步执行的,不会阻塞后面的代码,但如果使用了endInvoke监听的话同样会阻塞后面代码,此时的作用相当于invoke。
此处以一个10秒走表例子来说明问题
一、阻塞UI线程方法
private void button1_Click(object sender, EventArgs e) { for (int i = 1; i <=10;i++) { Thread.Sleep(1000); lblSecond.Text = i.ToString();//主线程会卡死 } }
二、创建新线程执行任务,并用control.Invoke更新UI显示
private void button2_Click(object sender, EventArgs e) { Thread myThread = new Thread(new ThreadStart(ShowSecond)); myThread.Start(); }
private delegate void showSecondDelegate();//定义一个委托 private void ShowSecond() { for (int i = 1; i <= 10; i++) { Thread.Sleep(1000); this.Invoke(new showSecondDelegate(delegate() //在委托方法中更新UI控件值 { lblSecond.Text = i.ToString(); //如果将thread.sleep放到此处,则会阻塞主线程,因为此处运行在主线程上 })); //后面的代码 //后面的代码会等invoke委托方法执行完成后再执行 //... } }
三、创建新线程执行任务,并用control.BeginInvoke更新UI显示
private void button3_Click(object sender, EventArgs e) { Thread myThread = new Thread(ShowSecond1); myThread.Start(); } private delegate void showSecondDelegate1(); private void ShowSecond1() { for (int i = 1; i <= 10; i++) { this.BeginInvoke(new showSecondDelegate1(delegate() { MessageBox.Show(i.ToString()); lblSecond.Text = i.ToString(); })); //后面的代码 //后面的代码会立即执行,不会等BeginInvoke委托方法执行完成后再执行 //... } }
四、创建新线程执行任务,并用control.BeginInvoke更新UI显示,使用control.EndInvoke监听结果,并阻塞当前线程
private delegate bool showSecondDelegate2(); /// <summary> /// 异步(beginInvoke更新UI-阻塞工作线程) /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button4_Click(object sender, EventArgs e) { Thread myThread = new Thread(ShowSecond2); myThread.Start(); } private void ShowSecond2() { for (int i = 1; i <= 10; i++) { Thread.Sleep(1000); IAsyncResult iasync = this.BeginInvoke(new showSecondDelegate2(delegate() { lblSecond.Text = i.ToString(); return true; })); object result = this.EndInvoke(iasync); //监听BeginInvoke委托方法执行结果,阻塞后面代码执行,直到委托方法执行完成 //后面的代码 //... } }
总结:
1、invoke和beginInvoke委托方法依然运行在主线程中,而不是当前线程,使用thread.sleep照样会阻塞主线程,所以耗时的操作应该放在工作线程中执行,更新UI显示
相关的代码放在委托方法中
2、在工作线程中想异步更新UI界面显示的话用beginInvoke,不影响后面代码运行
0 0
- c# Invoke和BeginInvoke
- C# invoke和beginInvoke
- C# invoke和begininvoke
- c# Invoke和BeginInvoke 区别
- c# Invoke和BeginInvoke 区别
- c# Invoke和BeginInvoke 区别
- c# Invoke和BeginInvoke 区别
- c# Invoke和BeginInvoke 区别
- c# Invoke和BeginInvoke 区别
- c# Invoke和BeginInvoke 区别
- c# Invoke和BeginInvoke 区别
- c# Invoke和BeginInvoke 区别
- c# Invoke和BeginInvoke 区别
- c# Invoke和BeginInvoke 区别
- c# Invoke和BeginInvoke 区别
- c# Invoke和BeginInvoke 区别
- c# Invoke和BeginInvoke 区别
- c# Invoke和BeginInvoke 区别
- CUDA中grid、block、thread、warp与SM、SP的关系
- Linux GPIO驱动 - 硬件及硬件抽象层
- AD PCF8591芯片学习(未完待续)
- 正则表达式
- ECharts+百度地图网络拓扑图应用
- C# invoke和beginInvoke
- IOS开发8---APP应用程序图标 及 程序启动画面设置。
- c++学习 ( new, delete)
- android多屏设计、适配(来自官网)
- try语句的用法
- java对elasticsearch操作
- SVM
- 心态开放并积极学习的人,运气都不会太坏。
- Java servlet解决中文乱码的解决方案