在 Windows Forms 應用程式中加入「載入動畫」並不簡單:解決「UI 執行緒阻塞」問題。
以下是說明、實作步驟及範例程式碼。
當一個表單(Form)取得操作焦點時,其他在背景運行的表單將暫停動作。
因此,當載入動畫出現時,必須另開執行緒在背景中執行接著要顯示的新表單,才能讓動畫持續播放。
這時又產生了一個問題...
由於新表單是透過另一個執行緒開啟的,當新表單顯示時,該執行緒會取得控制權成為主執行緒,
而負責動畫的執行緒則失去控制權,使得關閉動畫的操作無法順利執行。
因此,必須將「關閉動畫」的指令交由處理新表單的執行緒來執行。
藉由使用 async / await 關鍵字,能用最少的程式碼完成以上流程。
private async void btnOpenForm2_Click(object sender, EventArgs e)
{
using (var formLoading = new FormLoading())
{
// 在背景執行緒初始化 Form2,完成後關閉動畫再顯示 Form2
var loadForm2Task = Task.Run(() =>
{
var form2 = new Form2();
formLoading.DialogResult = DialogResult.OK;
form2.ShowDialog();
});
// 以Dialog顯示loading form,鎖住其他的表單強迫使用者等待
formLoading.ShowDialog();
// 等待 Form2 完成初始化並顯示
await loadForm2Task;
}
}
public Form2()
{
InitializeComponent();
LoadData();
}
private void LoadData()
{
// 模擬載入時間 (非同步等待 5 秒)
Thread.Sleep(5000);
Label lbl = new Label { Text = "loading complete", AutoSize = true };
this.Controls.Add(lbl);
}
public FormLoading()
{
InitializeComponent();
this.StartPosition = FormStartPosition.CenterParent;
this.FormBorderStyle = FormBorderStyle.None;
}
本文同步發表至我的Blog