实现 winform 异步跨线程访问UI控件
实现 winform 异步跨线程访问UI控件
在开发winform时经常会用到多线程防止界面出现假死现象,比如当你单击某个按钮时,需要执行很多代码,但是在执行过程中想实时的将当前执行的情况报告给用户,类型进度条或文本什么的。
这个时候很显然,如果你把要实现的内容放在按钮方法里时,其实界面要等这个按钮执行完后才能输出来,这个时候就达不到我们的预期了;那么怎么才能解决问题呢。
我初略终结了一下有以下几种方法:
1.采用BackgroundWorker控件,这个控件将要实时输出的内容写在事件中;
1 private void button1_Click( object sender, EventArgs e)
2 {
3 // 异步执行逻辑
4 backgroundWorker1.RunWorkerAsync();
5 }
6 private void backgroundWorker1_DoWork( object sender, DoWorkEventArgs e)
7 {
8 // 实现业务逻辑
9 int i = 5 ;
10 i = Math.Abs(i);
11 // 报告当前处理进度
12 backgroundWorker1.ReportProgress( 50 );
13 }
14
15 private void backgroundWorker1_ProgressChanged( object sender, ProgressChangedEventArgs e)
16 {
17 // 当前进度
18 int cuur = e.ProgressPercentage;
19 // 实现跨线程控件的输出
20 this .label1.Text = cuur.ToString();
21 }
22
23 private void backgroundWorker1_RunWorkerCompleted( object sender, RunWorkerCompletedEventArgs e)
24 {
25 // 执行完毕可以报告信息
26 this .label1.Text = " ok " ;
27 }
2.采用委托的方式实现灵活引用Invoke;
1 private void button2_Click( object sender, EventArgs e)
2 {
3 // 异步执行逻辑
4 Thread thread = new Thread(ThreadFunc);
5 thread.IsBackground = true ;
6 thread.Start();
7 }
8 private void ThreadFunc()
9 {
10 // 实现业务逻辑
11 int i = 5 ;
12 i = Math.Abs(i);
13 // 报告当前处理进度
14 SetLabel(i.ToString());
15 }
16 // 定义委托
17 delegate void SetLabelHandler( string text);
18 // 实现方法
19 private void SetLabel( string text)
20 {
21 if (InvokeRequired)
22 {
23 Invoke( new SetLabelHandler(SetLabel), text);
24 }
25 else
26 {
27 this .label1.Text = text;
28 }
29 }
3.采用Lamada表达式动态实现委托调用。
1 private void button3_Click( object sender, EventArgs e)
2 {
3 // 异步执行逻辑
4 Thread thread = new Thread(Func);
5 thread.IsBackground = true ;
6 thread.Start();
7 }
8 private void Func()
9 {
10 // 实现业务逻辑
11 int i = 5 ;
12 i = Math.Abs(i);
13 // 报告当前处理进度
14 AsyncUI(() => { label1.Text = i.ToString(); });
15 }
16 public void AsyncUI(Action action)
17 {
18 if (InvokeRequired)
19 {
20 Invoke(action);
21 }
22 else
23 {
24 action();
25 }
26 }
以上是我总结的三种,至于有没有其他方法,欢迎大家来拍砖,在这里我想推荐的是第三种方法,这个方法最灵活。
下面来谈谈我对这三种的看法:
对应第一种方法:使用简单,拖控件就ok,但是对应需要显示更负责的数据时比较麻烦;
对应第二种方法:可以不用拖控件来自由定制,但是同第一种方法一样,如果需要显示更多控件数据,也要定义很多方法和委托,太冗余累赘;
对于第三种方法:我个人非常喜欢,代码在需要的时候动态使用,但是我也没有仔细分析该方法的性能问题。
标签: 异步 , winform , lamada , c#
作者: Leo_wl
出处: http://HdhCmsTestcnblogs测试数据/Leo_wl/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
版权信息查看更多关于实现 winform 异步跨线程访问UI控件的详细内容...