C# 多线程刷新UI
阅读原文时间:2023年07月11日阅读:1

2.利用委托调用--最常见的办法(仅WinForm有效) 
  

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

namespace ThreadTest 

    public partial class Form1 : Form 
    { 
        delegate void D(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 (textBox1.InvokeRequired) 
            { 
                D d = new D(); 
                textBox1.Invoke(d,obj); 

            } 
            else  
            { 
                this.textBox1.Text = obj.ToString(); 
            } 
        } 

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

3.利用SynchronizationContext上下文 -- 最神秘的方法(Winform/Silverlight能用) 

之所以说它神秘,是因为msdn官方对它的解释据说也是不清不楚  
  

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

namespace ThreadTest 

    public partial class Form1 : Form 
    { 
        public Form1() 
        { 
            InitializeComponent();             
        }        

        private void btnSet_Click(object sender, EventArgs e) 
        { 
            Thread t = new Thread(new ParameterizedThreadStart(Run)); 
            MyPram _p = new MyPram() { context = SynchronizationContext.Current, parm = "Hello World" }; 
            t.Start(_p); 
        } 

        void Run(object obj)  
        { 
            MyPram p = obj as MyPram; 
            p.context.Post(SetTextValue, p.parm); 
        } 

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

    public class MyPram  
    { 
        public SynchronizationContext context { set; get; } 
        public object parm { set; get; } 
    } 

4.利用BackgroundWorker --最偷懒的办法(Winform/Silverlight通用) 

BackgroundWorker会在主线程之外,另开一个后台线程,我们可以把一些处理放在后台线程中处理,完成之后,后台线程会把结果传递给主线程,同时结束自己。 

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