C# winform处理多线程更新到UI控件

        单线程的winfom程序中,设置一个控件的值是很easy的事情,直接 this.TextBox1.value = "Hello World!";就搞定了,但是如果在一个新线程中这么做,比如: 

private void btnSet_Click(object sender, EventArgs e) 
{     
    Thread t = new Thread(new ParameterizedThreadStart(SetTextBoxValue)); 
    //当然也可以用匿名委托写成Thread t = new Thread(SetTextBoxValue); 
    t.Start("Hello World"); 
} 


void SetTextBoxValue(object obj)  
{ 
    this.textBox1.Text = obj.ToString(); 
} 


 运行时,会报出一个无情的错误: 
线程间操作无效: 从不是创建控件“textBox1”的线程访问它。 

原因,winform中的UI控件不是线程安全的,如果可以随意在任何线程中改变其值,你创建一个线程,我创建一个线程,大家都来抢着更改"TextBox1"的值。

第一种方式:Control.CheckForIllegalCrossThreadCalls = false;

 

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(); 
        }         
    } 
} 


设置Control.CheckForIllegalCrossThreadCalls为false,相当于不检测线程之间的冲突,允许各路线程随便乱搞,当然最终TextBox1的值到底是啥难以预料,只有天知道,不过这也是最省力的办法 。

 

第二种方式:利用委托调用

 

using System; 
using System.Threading; 
using System.Windows.Forms; 

namespace ThreadTest 
{ 
    public partial class Form1 : Form 
    { 
        delegate void AsynUpdateUI(object obj); 

        public Form1() 
        { 
            InitializeComponent();             
        } 
        

        private void btnSet_Click(object sender, EventArgs e) 
        {            
            Thread t = new Thread(new ParameterizedThreadStart(SetTextBoxValue)); 
            t.Start("Hello World"); 
        } 


        void SetTextBoxValue(object obj)  
        { 
            if (InvokeRequired) 
            { this.Invoke(new AsynUpdateUI(delegate(object obj) 
	
              {
                this.textBox1.Text = obj.ToString();
             }), obj);                    
} else { this.textBox1.Text = obj.ToString(); } } } }


 

发表评论 / Comment

用心评论~