实现 winform 异步跨线程访问UI控件
在开发winform时经常会用到多线程防止界面出现假死现象,比如当你单击某个按钮时,需要执行很多代码,但是在执行过程中想实时的将当前执行的情况报告给用户,类型进度条或文本什么的。
这个时候很显然,如果你把要实现的内容放在按钮方法里时,其实界面要等这个按钮执行完后才能输出来,这个时候就达不到我们的预期了;那么怎么才能解决问题呢。
我初略终结了一下有以下几种方法:
.采用BackgroundWorker控件,这个控件将要实时输出的内容写在事件中;
private void button1_Click(object sender, EventArgs e)
{
//异步执行逻辑
backgroundWorker1.RunWorkerAsync();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
//实现业务逻辑
int i = ;
i = Math.Abs(i);
//报告当前处理进度
backgroundWorker1.ReportProgress();
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
//当前进度
int cuur = e.ProgressPercentage;
//实现跨线程控件的输出
this.label1.Text = cuur.ToString();
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
//执行完毕可以报告信息
this.label1.Text = "ok";
}
.采用委托的方式实现灵活引用Invoke;
private void button2_Click(object sender, EventArgs e)
{
//异步执行逻辑
Thread thread = new Thread(ThreadFunc);
thread.IsBackground = true;
thread.Start();
}
private void ThreadFunc()
{
//实现业务逻辑
int i = ;
i = Math.Abs(i);
//报告当前处理进度
SetLabel(i.ToString());
}
//定义委托
delegate void SetLabelHandler(string text);
//实现方法
private void SetLabel(string text)
{
if (InvokeRequired)
{
Invoke(new SetLabelHandler(SetLabel), text);
}
else
{
this.label1.Text = text;
}
}
.采用Lamada表达式动态实现委托调用。
private void button3_Click(object sender, EventArgs e)
{
//异步执行逻辑
Thread thread = new Thread(Func);
thread.IsBackground = true;
thread.Start();
}
private void Func()
{
//实现业务逻辑
int i = ;
i = Math.Abs(i);
//报告当前处理进度
AsyncUI(() => { label1.Text = i.ToString(); });
}
public void AsyncUI(Action action)
{
if (InvokeRequired)
{
Invoke(action);
}
else
{
action();
}
}
以上是我总结的三种,至于有没有其他方法,欢迎大家来拍砖,在这里我想推荐的是第三种方法,这个方法最灵活。
下面来谈谈我对这三种的看法:
对应第一种方法:使用简单,拖控件就ok,但是对应需要显示更负责的数据时比较麻烦;
对应第二种方法:可以不用拖控件来自由定制,但是同第一种方法一样,如果需要显示更多控件数据,也要定义很多方法和委托,太冗余累赘;
对于第三种方法:我个人非常喜欢,代码在需要的时候动态使用,但是我也没有仔细分析该方法的性能问题。
实现 winform 异步跨线程访问UI控件的更多相关文章
- 理解SynchronizationContext,如何在Winform里面跨线程访问UI控件
SynchronizationContext 类是一个基类,可提供不带同步的自由线程上下文. 此类实现的同步模型的目的是使公共语言运行库内部的异步/同步操作能够针对不同的异步模型采取正确的行为.此模型 ...
- 跨线程访问UI控件时的Lambda表达式
工作中经常会用到跨线程访问UI控件的情况,由于.net本身机制,是不允许在非UI线程访问UI控件的,实际上跨线程访问UI控件还是 将访问UI的操作交给UI线程来处理的, 利用Control.Invok ...
- WPF / Win Form:多线程去修改或访问UI线程数据的方法( winform 跨线程访问UI控件 )
WPF:谈谈各种多线程去修改或访问UI线程数据的方法http://www.cnblogs.com/mgen/archive/2012/03/10/2389509.html 子线程非法访问UI线程的数据 ...
- 实现跨线程访问UI控件的3种方法
namespace 多线程 { public partial class Form2 : Form { public Form2() { InitializeComponent(); } privat ...
- (转).NET 4.5中使用Task.Run和Parallel.For()实现的C# Winform多线程任务及跨线程更新UI控件综合实例
http://2sharings.com/2014/net-4-5-task-run-parallel-for-winform-cross-multiple-threads-update-ui-dem ...
- Visual studio之C#跨线程调用UI控件
背景 当前串口通讯项目,多个线程需要同时利用richTextBoxMsg控件打印信息,直接调用会造成线程不安全,严重的时候会直接导致UI线程挂掉,因此本篇就跨线程调用UI控件做个记录. 正文 定义控件 ...
- C# Winform 跨线程更新UI控件常用方法汇总(多线程访问UI控件)
概述 C#Winform编程中,跨线程直接更新UI控件的做法是不正确的,会时常出现“线程间操作无效: 从不是创建控件的线程访问它”的异常.处理跨线程更新Winform UI控件常用的方法有4种:1. ...
- C# Winform 跨线程更新UI控件常用方法总结(转)
出处:http://www.tuicool.com/articles/FNzURb 概述 C#Winform编程中,跨线程直接更新UI控件的做法是不正确的,会时常出现“线程间操作无效: 从不是创建控件 ...
- 跨线程操作UI控件
写程序的时候经常会遇到跨线程访问控件的问题,看到不少人去设置Control.CheckForIllegalCrossThreadCalls = false;这句话是告诉编译器不要对跨线程访问作检查,可 ...
随机推荐
- Spark RDD/Core 编程 API入门系列之map、filter、textFile、cache、对Job输出结果进行升和降序、union、groupByKey、join、reduce、lookup(一)
1.以本地模式实战map和filter 2.以集群模式实战textFile和cache 3.对Job输出结果进行升和降序 4.union 5.groupByKey 6.join 7.reduce 8. ...
- 佛山Uber优步司机奖励政策(2月1日~2月7日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- iOS开发之状态栏UIStatusBar图标操作
NSArray *subIcons = [[[[UIApplication sharedApplication] valueForKeyPath:@"statusBar"] val ...
- IAR右键无法跳转到定义 的解决方法
用IAR编译程序,有时候编译通过了,但是右键无法GO TO Definition 解决方法有两个: 第一.Tools -> Option -> Project 把Generate br ...
- 实用的Android代码片段集合(精)
1.精确获取屏幕尺寸(例如:3.5.4.0.5.0寸屏幕) public static double getScreenPhysicalSize(Activity ctx) { DisplayMetr ...
- 在code.org上自己写一个flappy bird游戏
博客搬到了fresky.github.io - Dawei XU,请各位看官挪步.最新的一篇是:在code.org上自己写一个flappy bird游戏.
- java消息队列使用场景
http://blog.163.com/sir_876/blog/static/11705223201332444647261/ 目前能用到的比较不错的消息队列组件 ,kafka,activeMq, ...
- "http-8080-3" java.lang.OutOfMemoryError: PermGen space C3P0死锁的问题
Exception in thread ""http-bio-8080"-exec-1" java.lang.OutOfMemoryError: PermGen ...
- Bootstrap-基于jquery的bootstrap在线文本编辑器插件Summernote
Summernote是一个基于jquery的bootstrap超级简单WYSIWYG在线编辑器.Summernote非常的轻量级,大小只有30KB,支持Safari,Chrome,Firefox.Op ...
- 最简单的基于FFMPEG的视频编码器(YUV编码为H.264)
本文介绍一个最简单的基于FFMPEG的视频编码器.该编码器实现了YUV420P的像素数据编码为H.264的压缩编码数据.编码器代码十分简单,可是每一行代码都非常重要,适合好好研究一下.弄清楚了本代码也 ...