1 Winform 异步更新控件

刚才看到有人问为了winfrom中,在大数据绑定的时候出现画面假死的状态,为了解决这个问题希望通过再开一个线程来给控件绑定数据,可是画面还是会假死。
现在看到的方法有
1.掩耳盗铃法(Control.CheckForIllegalCrossThreadCalls?=?false;)

C# code

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

using?System;

using?System.Threading;

using?System.Windows.Forms;

?

namespace?ThreadTest

{

????public?partial?class?Form1?:?Form

????{????????

?

????????public?Form1()

????????{

????????????InitializeComponent();

????????????Control.CheckForIllegalCrossThreadCalls?=?false;//这一行是关键??????

????????}

????????

?

????????private?void?btnSet_Click(object?sender,?EventArgs?e)

????????{???????????

????????????Thread?t?=?new?Thread(new?ParameterizedThreadStart(SetTextBoxValue));

????????????t.Start("Hello?World");

????????}

?

?

????????void?SetTextBoxValue(object?obj)?

????????{

????????????this.textBox1.Text?=?obj.ToString();

????????}????????

????}

}

这种方法是最方便,实现最简单的方式,但是这样等于是线程之间是去了限制,子线程能够直接控制父线程的控件,会出现线程之间的冲突,不是好的实现方式
2.利用BackgroundWorker

C# code

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

using?System;

using?System.ComponentModel;

using?System.Windows.Forms;

?

namespace?ThreadTest

{

????public?partial?class?Form1?:?Form

????{

????????public?Form1()

????????{

????????????InitializeComponent();????????????

????????}???????

?

????????private?void?btnSet_Click(object?sender,?EventArgs?e)

????????{

????????????//MessageBox.Show(Thread.CurrentThread.ManagedThreadId.ToString());

????????????using?(BackgroundWorker?bw?=?new?BackgroundWorker())

????????????{

????????????????bw.RunWorkerCompleted?+=?new?RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);

????????????????bw.DoWork?+=?new?DoWorkEventHandler(bw_DoWork);

????????????????bw.RunWorkerAsync("Hello?World");

????????????}

????????}

?

????????void?bw_DoWork(object?sender,?DoWorkEventArgs?e)

????????{

????????????//MessageBox.Show(Thread.CurrentThread.ManagedThreadId.ToString());

????????????e.Result?=?e.Argument;//这里只是简单的把参数当做结果返回,当然您也可以在这里做复杂的处理后,再返回自己想要的结果(这里的操作是在另一个线程上完成的)

????????}

?

????????void?bw_RunWorkerCompleted(object?sender,?RunWorkerCompletedEventArgs?e)

????????{

????????????//这时后台线程已经完成,并返回了主线程,所以可以直接使用UI控件了

????????????this.textBox1.Text?=?e.Result.ToString();

????????????//MessageBox.Show(Thread.CurrentThread.ManagedThreadId.ToString());

????????}???????

????}????

}

这种方式只能在异步结束后给控件赋值,
--即bw_DoWork是异步处理,异步处理过程中不能给控件赋值
--bw_RunWorkerCompleted方法中可以给控件赋值,可是这个过程不是异步的,如果在bw_RunWorkerCompleted中加上一个System.Threading.Thread.Sleep(3000);画面还是会假死
3.不使用BackgroundWorker,自己来写线程来实现类似于BackgroundWorker的处理

子线程给主线程成员赋值的迷惑

C# code

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

????????//?代码中自己定义的按钮(非显示按钮)

????????private?Button?testBtn?=?new?Button();

?

????????private?void?button1_Click(object?sender,?EventArgs?e)

????????{

????????????Thread?thr?=?new?Thread(ControlParent);

????????????thr.Start();

????????}

?

????????private?void?ControlParent()

????????{

????????????Thread.Sleep(3000);

????????????//?给自己定义的按钮赋值没有问题

????????????testBtn.Text?=?"eeee";

????????????//?给画面上显示的按钮赋值,InvalidOperationException错误(这里迷糊了,子线程不能直接给主线程赋值,那么主线程是什么?)

????????????this.button1.Text?=?"asda";//?InvalidOperationException!!!!!!!!!!!

????????}

这里的两个按钮,同样是属于一个类,只不过一个显示在画面上,另一个只定义了没有显示,为什么一个赋值成功,另一个就是败了,求大哥大姐们来个破解之法,感激不尽。
PS:窗体的this.BeginInvoke只能不阻塞后面代码的执行,不能解决画面假死

来自为知笔记(Wiz)

时间: 2024-12-10 08:15:43

1 Winform 异步更新控件的相关文章

VintaSoft Twain .net控件可用于桌面应用WinForm的扫描仪控件

VintaSoftTwain.NET SDK是成熟的扫描组件. 利用它, 程序员可以从.net和wpf的应用中控制的平板和ADF扫描仪,网络和数码相机和任何其他TWAIN设备. NET SDK提供的TWAIN .NET SDK 包括的两个版本:<标准版> 或 <标准+ WPF版本>. 功能特点: 完全兼容TWAIN 1.x和2.x标准规范编程环境:.NET Framework 2.0或以上, WPF 3.5 或以上.纯.NET 托管代码库,可保证在NET Framework框架下有

C#winform中使用控件的Dock属性进行布局

想要实现如下布局,可以通过设置控件的Dock属性达到效果 1.拖放一个panel控件一个label控件(放在panel中)和一个treeView控件到TestForm中 2.设置panel的Dock属性为Top(设置BorderStyle属性为FixedSingle,这样显得美观些),设置treeView的Dock属性为Fill 3.需要注意的是要先把panel放到TestForm中,先放treeView就会使得treeView填充TestForm而被后放置的panel遮盖,如下所示 4.想要实

WINFORM 自定义开关按钮控件-

本文章转载:http://www.cnblogs.com/feiyangqingyun/archive/2013/06/15/3137597.html OK,大工告成,上图演示效果. 源码下载:http://files.cnblogs.com/feiyangqingyun/myButtonCheckTest.zip WINFORM 自定义开关按钮控件-,布布扣,bubuko.com

WinForm 清空界面控件值的小技巧

原文:WinForm 清空界面控件值的小技巧 在WinForm里面有时候需要清空自己输入内容或是选择的选项,以便重新操作流程,那么一般你是怎么清空界面各个控件值的呢?如果窗体里面控件,尤其是TextBox控件比较多的时候,代码里面是不是要设置每个控件的Text属性值为空呢?下面我用这个例子,来探讨下清空界面控件值的小技巧.而且还能复用.不必每个窗体都做这些枯燥.无聊的工作. 一般的做法是在清除控件的事件里面添加下面这样的代码: 代码 private void btnClear_Click(obj

Atitit. .net c# web 跟客户端winform 的ui控件结构比较

Atitit. .net c# web 跟客户端winform 的ui控件结构比较 .net   4.5 webform Winform 命名空间 System.Web.UI.WebControls System.Windows.Forms 命名空间 继承层次结构 System.Object System.Web.UI.Control System.Web.UI.WebControls.WebControl System.Web.UI.WebControls.Button 继承层次结构 Syst

Winform中checklistbox控件的常用方法

Winform中checklistbox控件的常用方法最近用到checklistbox控件,在使用其过程中,收集了其相关的代码段1.添加项checkedListBox1.Items.Add("蓝色"); checkedListBox1.Items.Add("红色"); checkedListBox1.Items.Add("黄色"); 2. 判断第i项是否选中,选中为true,否则为falseif(checkedListBox1.GetItemCh

WinForm之中BindingNavigator控件的使用

WinForm之中BindingNavigator控件的使用在微软WinForm中,BindingNavigator控件主要用来绑定数据.可以将一个数据集合与该控件绑定,以进行数据 联动的显示效果.如图下图所示: 那么,下面我们就来用BindingNavigator控件做一下上图所示的效果.分析:该案例以BindingNavigator控件为主线,我们定义一个实体类,将实体类以集合的形式显示在DataGridView中, 同时,将BindingNavigator与DataGridView绑定,将

WinForm界面布局控件WeifenLuo.WinFormsUI.Docking&quot;的使用 (二)

WinForm界面布局控件WeifenLuo.WinFormsUI.Docking"的使用 (二) 编写人:CC阿爸 2015-1-29 今天我想与大家继续一起分享这一伟大的控件.有兴趣的同学,可以一同探讨与学习一下,否则就略过吧. 1.    DockPanel的一点点改进: 在浏览网上的一些技术文章发现,的确有些地方还是可以进一步改进,如当双击Tab时,原先是直接把当前Tab所表示的这个窗体,从主窗体的框架上分离现来,成为一个浮动的窗体.这不是我们想要的,有些同学修改源代码,把它改成了双击关

WinForm界面布局控件WeifenLuo.WinFormsUI.Docking&quot;的使用 (一)

WinForm界面布局控件WeifenLuo.WinFormsUI.Docking"的使用 (一) 编写人:CC阿爸 2015-1-28 在伍华聪的博客中,看到布局控件"WeifenLuo.WinFormsUI.Docking",发现的确是一个非常棒的开源控件,用过的人都深有体会,该控件之强大.美观.不亚于商业控件.而且控件使用也是比较简单的今天在这里,我想与大家一起分这一伟大的控件.有兴趣的同学,可以一同探讨与学习一下,否则就略过吧. 一.引用方法: 1.建立一个WinFo