zoukankan      html  css  js  c++  java
  • 利用BackgroundWorker实现通用并行处理进度对话框

    四核的CPU普及了,.NET 4.0来了,并行编程似乎变得越来越普遍了。在最近的一个项目里,我尝试着引入了.NET 4.0在并行处理方面提供的一些新的技术,使代码更加简洁,也更易维护了。

    在典型的后台查询、前台显示查询进度的对话框设计上,依照以往的方式,我通常是利用delegate.BeginInvoke()方法,通过预定的Callback方法实现UI更新。而使用BackgroundWorker这个类,实现了基于事件的异步模式之后,这项工作变得轻松了许多。

    以下是我用Winform实现的一个简单示例,尽可能地保证了显示进度对话框的封闭性和代码简洁性。

    源代码下载(7zip压缩)


    一、显示进度对话框ProgressDlg的实现

    public partial class ProgressDlg : Form
    {
        public ProgressDlg()
        {
            InitializeComponent();
        }
    
        public void OnProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            // show the progress.
            this.progressBar.Value = e.ProgressPercentage;
        }
    
        public void OnCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            // thread is completed, close the dialog.
            this.progressBar.Value = 100;
            this.Close();
        }
    
        public CancelEventHandler OnCancel = null;
    
        private void btnCancel_Click(object sender, EventArgs e)
        {
            // thread is cancelled, close the dialog.
            this.Close();
        }
    
        private void ProgressDlg_FormClosed(object sender, FormClosedEventArgs e)
        {
            // cast notification of cancellation.
            if (this.OnCancel != null)
                this.OnCancel(this, new CancelEventArgs());
        }
    }
    

    二、主窗口MainForm的实现

    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
    
            this._backworker = new BackgroundWorker();
            // it's neccessary to set the properties.
            this._backworker.WorkerReportsProgress = true;
            this._backworker.WorkerSupportsCancellation = true;
    
            this._backworker.DoWork += new DoWorkEventHandler(backworker_DoWork);
            this._backworker.ProgressChanged += new ProgressChangedEventHandler(backworker_ProgressChanged);
            this._backworker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backworker_RunWorkerCompleted);
        }
    
        private BackgroundWorker _backworker = null;        
    
        // body of thread
        void backworker_DoWork(object sender, DoWorkEventArgs e)
        {
            for (int i = 0; i < 100; i++)
            {
                Thread.Sleep(100);
    
                // trigger the event: ProgressChanged
                this._backworker.ReportProgress(i);
    
                // if receive the notification of Cancel.
                if (this._backworker.CancellationPending)
                {
                    e.Cancel = true;
                    return;
                }
            }
        }
    
        void backworker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            // to do nothing.
        }
    
        void backworker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            // if thread is completed because of cancellation.
            if (e.Cancelled)
                this.labelSummary.Text = "Calculation is cancelled";
    
            this.btnCalculate.Enabled = true;
        }
    
        void backworker_OnCancel(object sender, CancelEventArgs e)
        {
            this._backworker.CancelAsync();            
        }
    
        private void btnCalculate_Click(object sender, EventArgs e)
        {
            string temp = this.txtMax.Text.Trim();
            if (string.IsNullOrEmpty(temp))
                MessageBox.Show("Please input a valid integer.", "Validation", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            else
            {
                ProgressDlg progressDlg = new ProgressDlg();
                // if thread is executing, dialog will show the progress.
                this._backworker.ProgressChanged += new ProgressChangedEventHandler(progressDlg.OnProgressChanged);
                this._backworker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(progressDlg.OnCompleted);
                // if cancel in progressDlg, let me know and do something.
                progressDlg.OnCancel += new CancelEventHandler(backworker_OnCancel);
    
                this.btnCalculate.Enabled = false;
                progressDlg.Show();
                    
                // start the thread.
                this._backworker.RunWorkerAsync();
            }
        }
    }
    
    
    转载请注明出处及作者,谢谢!
  • 相关阅读:
    JDOJ 1090: 矩阵
    JDOJ 2236: Random Num
    浅谈区间DP
    NOIP 2006 能量项链
    小技巧—处理环形区间
    NOI 1995 石子合并
    洛谷 P5640 【CSGRound2】逐梦者的初心
    JDOJ 1101: 邦德I
    JDOJ 1104: 最佳挑水
    JDOJ 1098: 夏娜的菠萝包
  • 原文地址:https://www.cnblogs.com/Abbey/p/2174136.html
Copyright © 2011-2022 走看看