星期二 十二月 22, 2009 09:17

cSharp中BackgroundWorker的用法

Posted by 邵 明博

线程同步中,还有一个比较流行的类<BackgroundWorker>.

BackgroundWorker 类允许您在单独的专用线程上运行操作。耗时的操作(如下载和数据库事务)在长时间运行时可能会导致用户界面 (UI) 似乎处于停止响应状态。如果您需要能进行响应的用户界面,而且面临与这类操作相关的长时间延迟,则可以使用 BackgroundWorker 类方便地解决问题。

若要在后台执行耗时的操作,请创建一个 BackgroundWorker,侦听那些报告操作进度并在操作完成时发出信号的事件。可以通过编程方式创建BackgroundWorker,也可以将它从“工具箱”的“组件”选项卡中拖到窗体上。如果在 Windows 窗体设计器中创建 BackgroundWorker,则它会出现在组件栏中,而且它的属性会显示在“属性”窗口中。

若要设置后台操作,请为 DoWork 事件添加一个事件处理程序。在此事件处理程序中调用耗时的操作。若要启动该操作,请调用 RunWorkerAsync。若要收到进度更新通知,请对 ProgressChanged 事件进行处理。若要在操作完成时收到通知,请对 RunWorkerCompleted 事件进行处理。

下面这个例子,主要从这几个方面来谈 cancellation support and report progress

    public partial class Form1 : Form
    {
 
        public Form1()
        {
            InitializeComponent();
            this.backgroundWorker1.WorkerSupportsCancellation = true;
            this.backgroundWorker1.WorkerReportsProgress = true;
 
            this.backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
            this.backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
            this.backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
 
        }
 
        private void button1_Click(object sender, EventArgs e)
        {
            if (this.textBox1.Text != "" &amp;&amp; this.textBox2.Text != "")
            {
                ab a = new ab(int.Parse(this.textBox1.Text), int.Parse(this.textBox2.Text));
                this.backgroundWorker1.RunWorkerAsync(a);
            }
 
        }
 
        private void button2_Click(object sender, EventArgs e)
        {
            this.backgroundWorker1.CancelAsync();
        }
 
        void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            this.progressBar1.Value = e.ProgressPercentage;
        }
 
        void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Cancelled)
            {
                this.textBox3.Text = "Result :Canclled!";
                this.progressBar1.Value = 100;
            }
            else if (e.Error != null)
            {
                MessageBox.Show("Error Details : " + (e.Error as Exception).ToString());
            }
            else
            {
                    this.textBox3.Text = "Result :" + e.Result;
                    this.progressBar1.Value = 100;
             }
        }
 
        void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            //do something here backgroundly.
 
                for (int i = 0; i &lt; this.progressBar1.Maximum; i++)
                {
                    Thread.Sleep(50);
                    this.backgroundWorker1.ReportProgress(i);
 
                    if (this.backgroundWorker1.CancellationPending)
                    {
                        e.Cancel = true;
                        return;
                    }
 
                }
                ab a = (ab)e.Argument;
                e.Result = a.C;
 
            }
 
    }
 
    class ab
    {
        private int _a;
 
        public int A
        {
            get { return _a; }
            set { _a = value; }
        }
        private int _b;
 
        public int B
        {
            get { return _b; }
            set { _b = value; }
        }
        public ab(int a,int b)
        {
            this._a = a;
            this._b = b;
        }
 
        public int C
        {
            get { return _b + _a; }
        }
    }

Comment Form