Winfom 使用 BackgroundWorker 實現進度條

BackgroundWorker 簡介(來自百度)

  BackgroundWorker是·net裏用來執行多線程任務的控件,它允許編程者在一個單獨的線程上執行一些操作。耗時的操作(如下載和數據庫事務)在長時間運行時可能會導致用戶界面 (UI) 始終處於停止響應狀態。如果您需要能進行響應的用戶界面,而且面臨與這類操作相關的長時間延遲,則可以使用BackgroundWorker類方便地解決問題。

  場景:界面加載數據量略大或者執行一個比較耗時的操作,如果在該操作未完成之前操作界面,會出現停止響應的情況,這個時候界面就會出現假死狀態,當我們用到 BackgroundWorker 時可以良好的提示用戶加載進度。

屬性

  1.WorkerReportsProgress:輔助線程是否報告進度。

  2.WorkerSupportsCancellation:輔助線程是否支持取消。

  3.CancellationPending:獲取一個值,指示應用程序是否已請求取消後臺操作。

  4.IsBusy:獲取一個值,指示 BackgroundWorker 是否正在運行一步操作。

  5.WorkerReportsProgress:獲取或設置一個值,該值指示 BackgroundWorker 能否報告進度更新。 

方法

  1.RunWorkerAsync()開始執行後臺操作。(調用該方法後,將觸發 BackgroundWorker.DoWork 事件,並以異步的方式執行 DoWork 事件中的代碼)

  2.ReportProgress(): 引發 BackgroundWorker.ProgressChanged 事件。(調用該方法後,將觸發BackgroundWorker. ProgressChanged事件。另外,該方法包含了一個int類型的參數percentProgress,用來表示當前異步操作所執行的進度百分比)

  3.CancelAsync():請求取消掛起的後臺操作。(調用該方法將使 BackgroundWorker.CancellationPending 屬性設置爲True)

事件

  1.DoWork:操作開始時在另一個線程上運行的事件處理程序。(用於承載異步操作,當調用 BackgroundWorker.RunWorkerAsync() 時觸發)

  2.ProgressChanged:當輔助線程指示某些操作已經進行時引發。(當調用 BackgroundWorker.ReportProgress(int percentProgress) 方式時觸發該事件)

  3.RunWorkerCompleted:當輔助線程完成(無論成功、失敗還是取消)時引發。

代碼案例

Form1窗體設計:

 

Form1代碼:

using System;
using System.ComponentModel;
using System.Threading;
using System.Windows.Forms;

namespace BackgroundWorkerDemo
{
    public partial class Form1 : Form
    {
        ProgressForm form;

        int maxValue = 0;

        public Form1()
        {
            InitializeComponent();
            InitializeBackgroundWorker();
        }

        private void InitializeBackgroundWorker()
        {
            backgroundWorker1.WorkerReportsProgress = true;
            backgroundWorker1.WorkerSupportsCancellation = true;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            maxValue = Convert.ToInt32(textBox1.Text);
            form = new ProgressForm();  //顯示進度條窗體
            form.MaxProcessBarValue = maxValue;

            this.backgroundWorker1.RunWorkerAsync();  //運行backgroundWorker組件

            form.ShowDialog(this);
        }

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            for(int i=0;i< maxValue;i++)
            {
                if(form.IsCancle)
                {
                    backgroundWorker1.CancelAsync();
                }
                
                if(backgroundWorker1.CancellationPending)
                {
                    e.Cancel = true;
                    return;
                }
                else
                {
                    form.ChangeProcessValue(i);
                    Thread.Sleep(100);
                }
            }
        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                MessageBox.Show(e.Error.ToString());
                return;
            }
            if (!e.Cancelled)
                MessageBox.Show("處理完畢!");
            else
                MessageBox.Show("處理終止!");
       form.Close(); } } }

 

ProgressForm窗體設計:

 

ProgressForm代碼:

using System;
using System.Windows.Forms;

namespace BackgroundWorkerDemo
{
    public partial class ProgressForm : Form
    {
        /// <summary>
        /// 進度條的最大值
        /// </summary>
        public int MaxProcessBarValue { get; set; }

        public bool IsCancle { get; set; } = false;
        public ProgressForm()
        {
            InitializeComponent();

            this.Load += Form2_Load;
        }

        private void Form2_Load(object sender, EventArgs e)
        {
            this.progressBar1.Maximum = this.MaxProcessBarValue;
            this.progressBar1.Minimum = 0;
        }

        //取消
        private void btnCancel_Click(object sender, EventArgs e)
        {
            try
            {
                this.btnCancel.Enabled = false;
                IsCancle = true;
                this.Close();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message.ToString(), ex);
            }
        }
        internal void ChangeProcessValue(int v)
        {
            try
            {
                this.Invoke(new Action(() =>
                {
                    this.progressBar1.Value = v + 1;  //獲取異步任務的進度百分比
                    label1.Text = $"完成比:{ v + 1} / {this.MaxProcessBarValue}  {Math.Round((v+1)*1.0/this.MaxProcessBarValue * 100,2)}%";
                }));
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message.ToString(), ex);
            }
        }
    }
}

 

結果:

源碼:

  鏈接: https://pan.baidu.com/s/1Ba5iWWFRKV6wjcHl39qpIQ

  提取碼: sj7e

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章