WPF之BackgroundWorker


BackgroundWorker類允許您在單獨的線程上執行某個可能導致用戶界面(UI)停止響應的耗時操作,下面來介紹一下這個線程類BackgroundWorker,大家可以結合這位大佬的這篇文章,說的比較仔細

https://www.cnblogs.com/zhaoshujie/p/9634136.html

1.屬性

//bool類型,指示應用程序是否已請求取消后台操作。此屬性通常放在用戶執行的異步操作內部,用來判斷用戶是否取消執行異步操作。當執行BackgroundWorker.CancelAsync()方法時,該屬性值將變為True。

public bool CancellationPending { get; }

//bool類型,指示BackgroundWorker是否正在執行一個異步操作。此屬性通常放在BackgroundWorker.RunWorkerAsync()方法之前,避免多次調用RunWorkerAsync()方法引發異常。當執行BackgroundWorker.RunWorkerAsync()方法是,該屬性值將變為True。
public bool IsBusy { get; }

//bool類型,指示BackgroundWorker是否可以報告進度更新。當該屬性值為True是,將可以成功調用ReportProgress方法,默認為false

public bool WorkerReportsProgress { get; set; }

//bool類型,指示BackgroundWorker是否支持異步取消操作。當該屬性值為True是,將可以成功調用CancelAsync方法取消工作線程。

public bool WorkerSupportsCancellation { get; set; }

2.方法

//取消線程操作,屬性CancellationPending將變為True

public void CancelAsync ();

//執行該方法,將觸發ProgressChanged事件

public void ReportProgress (int percentProgress);

//開始執行線程操作,觸發DoWork事件,執行事件中的代碼

public void RunWorkerAsync ();

3.事件

//當執行RunWorkerAsync方法的時候觸發該事件

public event System.ComponentModel.DoWorkEventHandler DoWork;

//當執行ReportProgress方法的時候觸發該事件

public event System.ComponentModel.ProgressChangedEventHandler ProgressChanged;

//當線程操作完成、或者被取消、或者拋出異常的時候觸發該事件

public event System.ComponentModel.RunWorkerCompletedEventHandler RunWorkerCompleted;

4.接下來通過一個開始/結束/暫停/繼續執行線程的例子來說明

namespace LoginUI
{
    /// <summary>
    /// MainWindow.xaml 的交互邏輯
    /// </summary>
    public partial class LoadingWindow : Window
    {private BackgroundWorker _backgroundWorker;
        //初始化為終止狀態(true),那么該方法將一直工作
private ManualResetEvent manualReset = new ManualResetEvent(true);public LoadingWindow() { InitializeComponent(); } private void Window_Loaded(object sender, RoutedEventArgs e) { #region InitializeBackgroundWorker(); btnSatrt.Content = "開始"; btnStop.Content = "暫停"; btnEnd.Content = "結束"; #endregion } //執行后台線程 private void btnSatrt_Click(object sender, RoutedEventArgs e) { //開始執行后台操作 _backgroundWorker.RunWorkerAsync(); btnSatrt.IsEnabled = false; btnEnd.IsEnabled = true; } //暫停/繼續后台線程 private void btnStop_Click(object sender, RoutedEventArgs e) { if (btnStop.Content.ToString() == "暫停") { manualReset.Reset();//暫停當前線程的工作,發信號給waitOne方法,阻塞 btnStop.Content = "繼續"; } else { manualReset.Set();//繼續當前線程的工作,發信號給waitOne方法,繼續運行Waitone后面的代碼 btnStop.Content = "暫停"; } } //結束后台線程 private void btnEnd_Click(object sender, RoutedEventArgs e) { _backgroundWorker.CancelAsync(); btnSatrt.IsEnabled = true; btnEnd.IsEnabled = false; }      private void InitializeBackgroundWorker() { #region if (_backgroundWorker == null) _backgroundWorker = new BackgroundWorker(); //bool類型,指示BackgroundWorker是否可以報告進度更新。當該屬性值為True時,將可以成功調用ReportProgress方法 _backgroundWorker.WorkerReportsProgress = true; //bool類型,指示BackgroundWorker是否支持異步取消操作。當該屬性值為True是,將可以成功調用CancelAsync方法 _backgroundWorker.WorkerSupportsCancellation = true; //執行RunWorkerAsync方法后觸發DoWork,將異步執行backgroundWorker_DoWork方法中的代碼 _backgroundWorker.DoWork += new DoWorkEventHandler(backgroundWorker_DoWork); //執行ReportProgress方法后觸發ProgressChanged,將執行ProgressChanged方法中的代碼 _backgroundWorker.ProgressChanged += new ProgressChangedEventHandler(_backgroundWorker_ProgressChanged); //異步操作完成或取消時執行的操作,當調用DoWork事件執行完成時觸發。 _backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker_RunWorkerCompleted); #endregion } //backgroundWorker_DoWork完成后執行 private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { if((bool)e.Result==true) { progressBar.Value = 100; lstbLog.Items.Add("操作已完成"); MessageBox.Show("操作已完成"); } } private void _backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) {
            //ProgressPercentage是ReportProgress方法中第一個參數傳遞過來的
progressBar.Value = e.ProgressPercentage;
             //lstbLog是一個listView控件,UserState是ReportProgress方法中第二個參數傳遞過來的 lstbLog.Items.Add(e.UserState.ToString()); }
//backgroundWorker_DoWork是運行在非UI線程上的,因此該內部代碼應該避免與UI界面交互,交互的邏輯應該放到 //ProgressChanged和RunWorkerCompleted事件中 private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e) { for (int i=0;i<=100;i++) { ////如果ManualResetEvent的初始化為終止狀態(true),那么該方法將一直工作, //直到收到Reset信號,將阻塞。然后,直到收到Set信號,就繼續工作。 manualReset.WaitOne(); //可以通過調用CancelAsync方法設置CancellationPending的值為false if (_backgroundWorker.CancellationPending) { _backgroundWorker.ReportProgress(i, String.Format("{0}%,操作被用戶申請結束", i)); _backgroundWorker.ReportProgress(0, String.Format("已完成{0}%",0 )); e.Result = false; break; } //調用 ReportProgress 方法,會觸發ProgressChanged事件 _backgroundWorker.ReportProgress(i, String.Format("已完成{0}%", i)); System.Threading.Thread.Sleep(50); if (i == 100) { //執行DoWork方法完成,設置為True e.Result = true; } } }


點擊開始按鈕,開始執行


點擊結束,將會結束上述任務

 

 點擊暫停/繼續按鈕可以暫停/繼續當前任務

 

上述每個按鈕的功能邏輯還沒有完善,但是基本的功能都實現了。本人也是個新手,如有什么問題麻煩指出,謝謝各位大佬!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM