实现 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;这句话是告诉编译器不要对跨线程访问作检查,可 ...
随机推荐
- 文件上传工具swfupload[转]
转至:http://zhangqgc.iteye.com/blog/906419 文件上传工具swfupload 示例: 1.JavaScript设置SWFUpload部分(与官方例子类似): var ...
- Java NIO使用及原理分析(二)
在第一篇中,我们介绍了NIO中的两个核心对象:缓冲区和通道,在谈到缓冲区时,我们说缓冲区对象本质上是一个数组,但它其实是一个特殊的数组,缓冲区对象内置了一些机制,能够跟踪和记录缓冲区的状态变化情况,如 ...
- load 与initialize的调用顺序小结
开发中实用方法固然是最贴近应用的,当一些程序原理还是要先搞清晰,根据查找的一些资料,总结了一些load与initialize的调用. APP启动到执行main函数之前,程序就执行了很多代码 执行顺 ...
- 会话数据的保存——cookie
会话的理解 可以简单的理解为:用户打开浏览器,访问多个web资源,然后关闭浏览器,这个过程可以称为一次会话 有状态会话:可以简单理解为一个同学来了这个教室,下一次再来我们知道他来过这个教室,我们可以称 ...
- Peterson算法与Dekker算法解析
进来Bear正在学习巩固并行的基础知识,所以写下这篇基础的有关并行算法的文章. 在讲述两个算法之前,需要明确一些概念性的问题, Race Condition(竞争条件),Situations lik ...
- hdu 寒冰王座
呵呵,过了这么久还来刷水题实在是不好意思.本题属于全然背包,就是一模板题.只是窝还是要来水一下.嘻嘻 寒冰王座 Time Limit: 2000/1000 MS (Java/Others) Me ...
- Java IO流学习总结(转)
Java流操作有关的类或接口: Java流类图结构: 流的概念和作用 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象.即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输 ...
- hadoop错误Operation category READ is not supported in state standby
报如下错误 解决方法: 方法一:(结果不起作用) 通过Shell命令方式,hadoop/bin/hdfs haadmin -failover --forceactive hadoop2 hadoop1 ...
- Flume NG中的Netcat Source
NetCat是一个非常简单的Unix工具,可以读.写TCP或UDP网络连接(network connection)中数据 在Flume中的netcat支持Flume与NetCat整合,flume可以使 ...
- 【Android】数据存储-SharedPreferences存储
简单介绍:SharedPreferences是使用键值对的方式来存储数据的,也就是说,当保存一条数据的时候,给这条数据提供一个键,如果需要读取数据,只需要通过这个键就可以提取到对应的数据. 一:存储数 ...