1,WPF應用程序爲單線程模型(STAThread),全部UI控件都是主線程建立的,只有主線程能操做UI元素的顯示。異步
2,其餘工做線程要維護UI控件的顯示,需調用主線程的Dispather,執行Invoke(同步)或BeginInvoke(異步)方法。this
3,UI線程如時行耗時的操做,將使UI假死,用戶體驗較差。應使用後臺線程進行耗時操做,並異步更新UI。spa
4,BackgroundWorker是WPF的一個後臺工做類,代碼說明一切:線程
前臺:code
<StackPanel> <ProgressBar Name="progressBar" Height="20" Width="200" Margin="10"></ProgressBar> <Button Name="btnProcess" Width="100" Click="btnProcess_Click" Margin="5">開始後臺任務</Button> <Button Name="btnCancel" Width="100" Click="btnCancel_Click" Margin="5">取消後臺任務</Button> </StackPanel>
後臺:blog
public partial class MainWindow : Window { BackgroundWorker bgWorker = new BackgroundWorker(); public MainWindow() { InitializeComponent(); bgWorker.WorkerReportsProgress = true; bgWorker.WorkerSupportsCancellation = true; bgWorker.DoWork += DoWork_Handler; bgWorker.ProgressChanged += ProgressChanged_Handler; bgWorker.RunWorkerCompleted += RunWorkerCompleted_Handler; } private void btnProcess_Click(object sender, RoutedEventArgs e) { if (!bgWorker.IsBusy) { bgWorker.RunWorkerAsync(); } } private void ProgressChanged_Handler(object sender, ProgressChangedEventArgs args) { progressBar.Value = args.ProgressPercentage; } //後臺線程運行的程序 private void DoWork_Handler(object sender, DoWorkEventArgs args) { BackgroundWorker worker = sender as BackgroundWorker; for (int i = 1; i <= 100; i++) { if (worker.CancellationPending) { args.Cancel = true; break; } else { worker.ReportProgress(i); //由於這在後臺線程,要想直接修改UI控件,需用Invoke或BeginInvoke方法 //this.Dispatcher.Invoke(new Action(() => //{ // progressBar.Value = i; //})); Thread.Sleep(100); //由於頻繁調用UI線程,爲了給UI線程反應時間,這裏讓後臺線程稍頓一下 } } } private void RunWorkerCompleted_Handler(object sender, RunWorkerCompletedEventArgs args) { progressBar.Value = 0; if (args.Cancelled) { MessageBox.Show("後臺任務已經被取消。", "消息"); } else { MessageBox.Show("後臺任務正常結束。", "消息"); } } private void btnCancel_Click(object sender, RoutedEventArgs e) { bgWorker.CancelAsync(); } }