1. 在开发winform时经常会用到多线程防止界面出现假死现象,比如当你单击某个按钮时,需要执行很多代码,但是在执行过程中想实时的将当前执行的情况报告给用户,类型进度条或文本什么的。
  2.  
  3. 这个时候很显然,如果你把要实现的内容放在按钮方法里时,其实界面要等这个按钮执行完后才能输出来,这个时候就达不到我们的预期了;那么怎么才能解决问题呢。
  4.  
  5. 我初略终结了一下有以下几种方法:
  6.  
  7. .采用BackgroundWorker控件,这个控件将要实时输出的内容写在事件中;
  8.  
  9. private void button1_Click(object sender, EventArgs e)
  10. {
  11. //异步执行逻辑
  12. backgroundWorker1.RunWorkerAsync();
  13. }
  14. private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
  15. {
  16. //实现业务逻辑
  17. int i = ;
  18. i = Math.Abs(i);
  19. //报告当前处理进度
  20. backgroundWorker1.ReportProgress();
  21. }
  22.  
  23. private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
  24. {
  25. //当前进度
  26. int cuur = e.ProgressPercentage;
  27. //实现跨线程控件的输出
  28. this.label1.Text = cuur.ToString();
  29. }
  30.  
  31. private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
  32. {
  33. //执行完毕可以报告信息
  34. this.label1.Text = "ok";
  35. }
  36.  
  37. .采用委托的方式实现灵活引用Invoke
  38.  
  39. private void button2_Click(object sender, EventArgs e)
  40. {
  41. //异步执行逻辑
  42. Thread thread = new Thread(ThreadFunc);
  43. thread.IsBackground = true;
  44. thread.Start();
  45. }
  46. private void ThreadFunc()
  47. {
  48. //实现业务逻辑
  49. int i = ;
  50. i = Math.Abs(i);
  51. //报告当前处理进度
  52. SetLabel(i.ToString());
  53. }
  54. //定义委托
  55. delegate void SetLabelHandler(string text);
  56. //实现方法
  57. private void SetLabel(string text)
  58. {
  59. if (InvokeRequired)
  60. {
  61. Invoke(new SetLabelHandler(SetLabel), text);
  62. }
  63. else
  64. {
  65. this.label1.Text = text;
  66. }
  67. }
  68.  
  69.   .采用Lamada表达式动态实现委托调用。
  70.  
  71. private void button3_Click(object sender, EventArgs e)
  72. {
  73. //异步执行逻辑
  74. Thread thread = new Thread(Func);
  75. thread.IsBackground = true;
  76. thread.Start();
  77. }
  78. private void Func()
  79. {
  80. //实现业务逻辑
  81. int i = ;
  82. i = Math.Abs(i);
  83. //报告当前处理进度
  84. AsyncUI(() => { label1.Text = i.ToString(); });
  85. }
  86. public void AsyncUI(Action action)
  87. {
  88. if (InvokeRequired)
  89. {
  90. Invoke(action);
  91. }
  92. else
  93. {
  94. action();
  95. }
  96. }
  97.  
  98. 以上是我总结的三种,至于有没有其他方法,欢迎大家来拍砖,在这里我想推荐的是第三种方法,这个方法最灵活。
  99.  
  100. 下面来谈谈我对这三种的看法:
  101.  
  102. 对应第一种方法:使用简单,拖控件就ok,但是对应需要显示更负责的数据时比较麻烦;
  103.  
  104. 对应第二种方法:可以不用拖控件来自由定制,但是同第一种方法一样,如果需要显示更多控件数据,也要定义很多方法和委托,太冗余累赘;
  105.  
  106. 对于第三种方法:我个人非常喜欢,代码在需要的时候动态使用,但是我也没有仔细分析该方法的性能问题。

实现 winform 异步跨线程访问UI控件的更多相关文章

  1. 理解SynchronizationContext,如何在Winform里面跨线程访问UI控件

    SynchronizationContext 类是一个基类,可提供不带同步的自由线程上下文. 此类实现的同步模型的目的是使公共语言运行库内部的异步/同步操作能够针对不同的异步模型采取正确的行为.此模型 ...

  2. 跨线程访问UI控件时的Lambda表达式

    工作中经常会用到跨线程访问UI控件的情况,由于.net本身机制,是不允许在非UI线程访问UI控件的,实际上跨线程访问UI控件还是 将访问UI的操作交给UI线程来处理的, 利用Control.Invok ...

  3. WPF / Win Form:多线程去修改或访问UI线程数据的方法( winform 跨线程访问UI控件 )

    WPF:谈谈各种多线程去修改或访问UI线程数据的方法http://www.cnblogs.com/mgen/archive/2012/03/10/2389509.html 子线程非法访问UI线程的数据 ...

  4. 实现跨线程访问UI控件的3种方法

    namespace 多线程 { public partial class Form2 : Form { public Form2() { InitializeComponent(); } privat ...

  5. (转).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 ...

  6. Visual studio之C#跨线程调用UI控件

    背景 当前串口通讯项目,多个线程需要同时利用richTextBoxMsg控件打印信息,直接调用会造成线程不安全,严重的时候会直接导致UI线程挂掉,因此本篇就跨线程调用UI控件做个记录. 正文 定义控件 ...

  7. C# Winform 跨线程更新UI控件常用方法汇总(多线程访问UI控件)

    概述 C#Winform编程中,跨线程直接更新UI控件的做法是不正确的,会时常出现“线程间操作无效: 从不是创建控件的线程访问它”的异常.处理跨线程更新Winform UI控件常用的方法有4种:1. ...

  8. C# Winform 跨线程更新UI控件常用方法总结(转)

    出处:http://www.tuicool.com/articles/FNzURb 概述 C#Winform编程中,跨线程直接更新UI控件的做法是不正确的,会时常出现“线程间操作无效: 从不是创建控件 ...

  9. 跨线程操作UI控件

    写程序的时候经常会遇到跨线程访问控件的问题,看到不少人去设置Control.CheckForIllegalCrossThreadCalls = false;这句话是告诉编译器不要对跨线程访问作检查,可 ...

随机推荐

  1. seq命令

    seq 5 seq 5 >1.txt 其中的>是覆盖 seq 1 5 用来产生从数1到数5之间的所有整数 或, seq 5

  2. 记录:Ubuntu下安装mysql

    >>更新源列表 在终端中输入:sudo apt-get update 更新完成后输入:sudo apt-get install mysql-server mysql-client 接着输入 ...

  3. JQuery- 动画与效果

    这几天做网站,刚好用到! 1.基本效果 匹配元素从左上角开始变浓变大或缩小到左上角变淡变小 ①隐藏元素 除了可以设置匹配元素的display:none外,可以用以下函数 hide(speed,[cal ...

  4. Linux TCP/IP parameters reference

    This is a reference of IP networking parameters that are configurable as described in our linux twea ...

  5. SQL Server 优化器+SQL 基础

    http://www.cnblogs.com/shanksgao/tag/%E4%BC%98%E5%8C%96%E5%99%A8/ http://www.cnblogs.com/double-K/ca ...

  6. [转] Putty - 文件夹显示的蓝色太暗

    Putty SSH key的后缀为ppk 默认文件夹的颜色显示为ANSI Blue,颜色太暗. ANSI Blue : RGB(0, 0, 187) 将ANSI Blue修改为和ANSI Blue B ...

  7. 浮动闭合方案:clearfix

    1 ;clear:both;visibility:hidden} .clearfix{*+height:1%;} 2 .clearfix{overflow:auto;_height:1%} 3 ;}

  8. nginx介绍及安装

    nginx(Engine x)      静态的www软件    特点:        配置简单        高并发,1-2w,基于异步IO模型(epoll,kqueue)        占用资源少 ...

  9. 【转】Java中equals和==的区别

    [转]Java中equals和==的区别 java中的数据类型,可分为两类: 1.基本数据类型,也称原始数据类型.byte,short,char,int,long,float,double,boole ...

  10. js--小结④

    举例子,一个demo.提醒自己经常性会在onclick 和function()这两个地方出错 onclick会输少一个字母 function会忘记输括号