winform异步线程更新UI问题

刚才看到有人问为了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只能不阻塞后面代码的执行,不能解决画面假死
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值