1.概要
2.需求及其运行效果
有一个线程自动加数,并通过一个label控件体现处理,效果如下图。
3.不同实现方式的代码
3.1 通过UI线程的SynchronizationContext的Post/Send方法更新
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace 线程更新ui方法总结
{
public partial class Form1 : Form
{
SynchronizationContext _syncContext = null;
public Form1()
{
InitializeComponent();
_syncContext = SynchronizationContext.Current;
run();
}
private void run()
{
Task t = new Task(() =>
{
int index = 0;
while (true)
{
Thread.Sleep(500);
_syncContext.Post(setLable, index++);
}
});
t.Start();
}
private void setLable(object o)
{
label1.Text = o.ToString();
}
}
}
3.2 通过UI控件的Invoke/BeginInvoke方法更新
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace 线程更新ui方法总结
{
public partial class Form1 : Form
{
SynchronizationContext _syncContext = null;
public Form1()
{
InitializeComponent();
_syncContext = SynchronizationContext.Current;
run();
}
private void run()
{
Action<String> AsyncUIDelegate = delegate (string n) { label1.Text = n; };//定义一个委托
Task t = new Task(() =>
{
int index = 0;
while (true)
{
Thread.Sleep(500);
label1.Invoke(AsyncUIDelegate, new object[] { index++.ToString() });
}
});
t.Start();
}
}
}
3.3 通过BackgroundWorker取代Thread执行异步操作
using System.ComponentModel;
using System.Threading;
using System.Windows.Forms;
namespace 线程更新ui方法总结
{
public partial class Form1 : Form
{
private BackgroundWorker backgroundWorker1 = null;
int index = 0;
public Form1()
{
InitializeComponent();
run();
}
private void run()
{
backgroundWorker1 = new System.ComponentModel.BackgroundWorker();
//设置报告进度更新
backgroundWorker1.WorkerReportsProgress = true;
//注册线程主体方法
backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
//注册更新UI方法
backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
this.backgroundWorker1.RunWorkerAsync();
}
//第二步:定义执行线程主体事件
//线程主体方法
public void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
while (true)
{
Thread.Sleep(500);
//...执行线程任务
index++;
//在线程中更新UI(通过ReportProgress方法)
backgroundWorker1.ReportProgress(50, index++);
//...执行线程其他任务
}
}
//第三步:定义执行UI更新事件
//UI更新方法
public void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
this.label1.Text = e.UserState.ToString();
}
}
}
3.4 通过设置窗体属性,取消线程安全检查来避免"线程间操作无效异常"(非线程安全,建议不使用)
using System.ComponentModel;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace 线程更新ui方法总结
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
//指定不再捕获对错误线程的调用
Control.CheckForIllegalCrossThreadCalls = false;
run();
}
private void run()
{
Task t = new Task(() =>
{
int index = 0;
while (true)
{
Thread.Sleep(500);
label1.Text = (index++).ToString();
}
});
t.Start();
}
}
}