異步線程調用UI更新,有兩種方式,一、用UI對象的Invoke方法用委託的方式進行調用操作UI的代碼,二、用事件驅動模式的BackGroundWorker組件進行UI操作,這是爲了線程安全。因爲BackGroundWorker是一個較爲常規的組件,在此不再多述,只就第一種方式進行簡單講解。
當然在編程過程中,線程安全要求,並非強制性的,因爲即便線程不安全,程序也有很大的機率能夠正常運行,不過不建議這麼做,這會給程序帶來很大的隱患。而且如果你想在這種線程不安全的情況下使用VS開發工具進行調試的話,一般情況下不會通過,因爲VS會主動引發InvalidOperationException異常來對你進行提醒,並且中斷你的調試,除非你在程序運行上下文中進行了如下設置:將Control.CheckForIllegalCrossThreadCalls設置爲false,用以禁用異常的產生,纔可以進行調試。
切記,如果要使用UI對象的Invoke方法從異步線程更改UI,若非萬不得已,此操作則最好僅用來操作UI更新,不要夾雜無關的邏輯處理代碼,不然依舊會耗費界面線程的佔用時間,造成反應遲緩或者假死。
如,這樣寫是不對的:
private void button1_Click(object sender, EventArgs e)
{
//開啓一個異步線程進行邏輯處理
new Task(new Action(() =>
{
//無關UI的耗時操作
Thread.Sleep(5000);
//調用UI線程進行界面更新
this.Invoke(new Action(() =>
{
//更新界面
this.Text = "233";
//其他無關UI的耗時操作,寫在這裏是不對的
Thread.Sleep(3000);
}));
})).Start();
}
應該這樣寫:
private void button1_Click(object sender, EventArgs e)
{
//開啓一個異步線程進行邏輯處理
new Task(new Action(() =>
{
//無關UI的耗時操作
Thread.Sleep(5000);
//調用UI線程進行界面更新
this.Invoke(new Action(() =>
{
//更新界面
this.Text = "233";
}));
//其他無關UI的耗時操作
Thread.Sleep(3000);
})).Start();
}
讓UI線程僅處理與顯示相關的代碼,可大幅度提升程序的響應速度和程序用戶的使用體驗,至於數據邏輯,除非必要,交給其他線程即可。