多線程學習筆記(二) BackgroundWorker 和 ProgressChanged


BackgroundWorker是在內部使用了線程池的技術;同時,在Winform 或WPF編碼中,它還給工作線程和UI線程提供了交互的能力。

Thread和ThreadPool默認都沒有提供這種交互能 力,而BackgroundWorker卻通過事件提供了這種能力。這種能力包括:報告進度、支持完成回調、取消任務、暫停任務等。

一般而言,無特殊需要的,優先考慮使用標准的backgroundworker
再加上線程池,多數問題都能應付了
只有特別需要精確控制或性能的才用thread

BackgroundWorker會在主線程之外,另開一個后台線程,

我們可以把一些處理放在后台線程中處理,完成之后,后台線程會把結果傳遞給主線程,同時結束自己。

如果要顯示進度,比如我們希望走馬燈式更新label,就要把 bw.WorkerReportsProgress = true;

如果要支持中途取消, 則把bw.WorkerSupportsCancellation = true; 

        private void button3_Click(object sender, EventArgs e)
        {
            using (BackgroundWorker bw = new BackgroundWorker())
            {
                bw.WorkerReportsProgress = true;
                bw.ProgressChanged += bw_ProgressChanged;
                bw.RunWorkerCompleted += bw_RunWorkerCompleted;
                bw.DoWork += bw_DoWork;

                //允許用戶指定顯示數據的范圍呢!所以需要把100作為參數傳遞給計算過程
                bw.RunWorkerAsync(100); 
            }

        }
        //這時返回了主線程,所以可以直接使用UI控件了
        void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            //修改進度條的顯示。
            //this.progressBarSum.Value = e.ProgressPercentage;

            //如果有更多的信息需要傳遞,可以使用 e.UserState 傳遞一個自定義的類型。
            //這是一個 object 類型的對象,您可以通過它傳遞任何類型。
            //我們僅把當前 sum 的值通過 e.UserState 傳回,並通過顯示在窗口上。
            string message = e.UserState.ToString();
            label1.Text = message;
        }
        //e.Argument=bw.RunWorkerAsync("Hello World")的參數
        void bw_DoWork(object sender, DoWorkEventArgs e)
        {
            System.Diagnostics.Debug.WriteLine("bw_DoWork");
            BackgroundWorker bgWorker = sender as BackgroundWorker;
            //這里的操作是在另一個線程上完成的,不應該操作UI
            //在這里執行耗時的運算。

            int endNumber = 0;
            if (e.Argument != null)
            {
                endNumber = (int)e.Argument;
            }

            for (int i = 0; i <= endNumber; i++)
            {
                bgWorker.ReportProgress(i, "current num:" + i.ToString());
                Thread.Sleep(50); //為了方便演示
            }
            
        }
        //這時后台線程已經完成,並返回了主線程,所以可以直接使用UI控件了
        void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            System.Diagnostics.Debug.WriteLine("bw_RunWorkerCompleted");
            if (e.Error == null)
                lblMsg.Text = "正常結束";
            else
                lblMsg.Text = "異常結束"+ e.Error.Message;
        }

 

 

參考: https://www.cnblogs.com/sparkdev/p/5906272.html

https://www.cnblogs.com/luminji/archive/2011/05/13/2044801.html

https://www.cnblogs.com/happy555/archive/2007/11/07/952315.html

https://www.cnblogs.com/grenet/archive/2011/12/21/2289014.html

我所知道的.NET異步  https://www.cnblogs.com/scy251147/archive/2012/03/03/2378477.html

支持暫停操作的Backgroundworker  https://www.cnblogs.com/chenxizhang/archive/2010/03/13/1685209.html


免責聲明!

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



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