轉載:https://www.cnblogs.com/atskyline/archive/2012/06/22/2558516.htmlhtml
簡介
但凡涉及到圖形界面,每每的設計都是不支持或者不推薦使用多個線程操做界面內容.並且一般會有一個專門的線程調度器來處理任務線程和界面線程的問題.下面提供兩個兩個方案.c#
使用Dispatcher.BeginInvoke
這個方法簡單暴力適合小工做量的修改一些界面內容.使用Dispatcher.BeginInvoke()會將代碼安排爲調度程序的一個任務.異步
步驟函數
- 使用Thread新建並開始一個線程
- 在新建的線程處理函數中須要修改界面的時候獲取界面的dispatcher
- 使用Dispatcher的BeginInvoke方法指定一個線程優先級,和一個委託,這個委託時用於修改界面內容的
下面給出一部分代碼this
//新建線程 Thread thread = new Thread(UpdateTextRight); thread.Start();
下面是新線程中的方法spa
//這個事例恰好是先窗體類中定義的,因此獲取Dispatcher變得比較方便,並且使用了匿名委託.在一般的代碼中會把委託給分離出去比較好. private void UpdateTextRight() { this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (ThreadStart) delegate() { txt.Text = "Here is some new text."; } ); }
使用BackgroupWorker
這個類是專門用於簡化Windows Form程序與線程相關的問題設計的,一樣適用於WPF程序.適合於一個長期的後臺進程,支持進度通知,取消支持,完成通知等功能.線程
使用方法也很簡單,建立一個BackfruopWorker實例,它有幾個事件.設計
DoWork事件會在另一個線程中執行,用RunWorkerAsync()啓動.因此在這個事件中不要去處理修改界面的事情code
RunWorkerCompleted事件,在DoWork事件返回時(正常或者異常返回),在圖形的線程中執行,因此能夠修改界面orm
ProgressChanged事件,使用ReportProgress()方法調用,同時是在圖形界面的線程中執行,一般負責修改一下進度條什麼的.而ReportProgress()方法,一般會在DoWork的事件中調用,而後給一個百分比的值.要使用這個功能,須要把WorkerReportsProgress屬性設置成true
另外值得一說的是,要取消支持須要把WorkerSupportsCancellation屬性設爲true,使用CancelAsync()方法調用,可是這個調用不會終止進程,因此在DoWork事件中須要判斷CancellationPending.
下面給出部分代碼
建立BackgroundWorker實例
BackgroundWorker backgroundWorker; backgroundWorker = new BackgroundWorker(); backgroundWorker.DoWork += backgroundWorker_DoWork; backgroundWorker.RunWorkerCompleted += backgroundWorker_RunWorkerCompleted; //能夠返回工做進度 backgroundWorker.WorkerReportsProgress = true; backgroundWorker.ProgressChanged += backgroundWorker_ProgressChanged; //容許取消 backgroundWorker.WorkerSupportsCancellation = true;
開始執行DoWork
backgroundWorker.RunWorkerAsync();
DoWork事件範例,這個方法的內容是在另一個線程,異步執行得
private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e) { while(!backgroundWorker.CancellationPending) { //Do SomeThing //在合適的時候使用 //backgroundWorker.ReportProgress(i); //報告一下進度,其中i是0-100的整數 } //這裏能夠使用e.Result給一個返回值,若是有須要的話 }
進度改變時的處理事件,也就是修改一下進度條什麼的
private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) { progressBar.Value = e.ProgressPercentage; }
完成事件我就不演示,下面是取消任務的方法
private void cmdCancel_Click(object sender, RoutedEventArgs e) { backgroundWorker.CancelAsync(); }