none
关于Backgroundworker的问题 RRS feed

  • 问题

  • 在网上看到一个C#中Backgroundworker的例子,想练习一下,总是运行不成功。朋友帮看一下。

    建了一个Win Form项目。

    一个 Progressbar,一个Lable,和三个Button

                this.button1 = new System.Windows.Forms.Button();
                this.button2 = new System.Windows.Forms.Button();
                this.button3 = new System.Windows.Forms.Button();
                this.progressBar1 = new System.Windows.Forms.ProgressBar();
                this.label1 = new System.Windows.Forms.Label();
                this.backgroundWorker1 = new System.ComponentModel.BackgroundWorker();


    代码如下:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    
    namespace WindowsFormsApplication3
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            //这里就是通过响应消息,来处理界面的显示工作
            private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
            {
                this.progressBar1.Value = e.ProgressPercentage;
                this.label1.Text = e.UserState.ToString();
                this.label1.Update();
            }
    
            //这里是后台工作完成后的消息处理,可以在这里进行后续的处理工作。
            private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
            {
                MessageBox.Show("处理完成了。");
            }
            
            //真正的处理工作
            private bool work(BackgroundWorker bk)
            {
                int tatle = 10000;
    
                for (int i = 0; i < tatle; i++)
                {
                    if (bk.CancellationPending) //这里判断一下是否用户要求取消后台进行,并可以尽早退出。
                    {
                        bk.ReportProgress(i, String.Format("当前值是 {0},操作被用户申请中断", i));
                        return false;
                    }
    
                    //处理的过程中,通过这个函数,向主线程报告处理进度,最好是折算成百分比,与外边的进度条的最大值必须要对应。这里,我没有折算,而是把界面线程的进度条最大值调整为与这里的总数一致。
                    bk.ReportProgress(i, String.Format("当前值是 {0} ", i));
                }
                return true;
            }
    
            private void button2_Click(object sender, EventArgs e)
            {
                //用户要求取消时,就这样处理一下。有时不太灵喔。
                this.backgroundWorker1.CancelAsync();
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                //这一句,就是让后台工作开始。
    
                this.progressBar1.Maximum = 10000;
                this.progressBar1.Minimum = 1;
                this.progressBar1.Value = 1;
    
                this.backgroundWorker1.RunWorkerAsync();
    
            }
    
            private void button3_Click(object sender, EventArgs e)
            {
                this.Close();
            }
    
            private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
            {
                //这里,就是后台进程开始工作时,调用工作函数的地方。你可以把你现有的处理函数写在这儿。
                work(this.backgroundWorker1);
            }
        }
    }

    点击运行后弹出异常:

    下面是我的Form的界面:

    下面是Programme.cs内容:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Windows.Forms;
    
    namespace WindowsFormsApplication3
    {
        static class Program
        {
            /// <summary>
            /// 应用程序的主入口点。
            /// </summary>
            [STAThread]
            static void Main()
            {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Application.Run(new Form1());
            }
        }
    }


    • 已编辑 Azurewrath 2014年11月6日 17:12 补充信息
    2014年11月6日 17:02

答案

  • 你好,

    我跑了一下你的Code发现错误比较多,所以在不太明白你的逻辑下我建议你还是先参考下MSDN文档是怎么做的:
    http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker(v=vs.110).aspx

    using System;
    using System.ComponentModel;
    using System.Windows.Forms;
    
    namespace BackgroundWorkerSimple
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
                backgroundWorker1.WorkerReportsProgress = true;
                backgroundWorker1.WorkerSupportsCancellation = true;
            }
    
            private void startAsyncButton_Click(object sender, EventArgs e)
            {
                if (backgroundWorker1.IsBusy != true)
                {
                    // Start the asynchronous operation.
                    backgroundWorker1.RunWorkerAsync();
                }
            }
    
            private void cancelAsyncButton_Click(object sender, EventArgs e)
            {
                if (backgroundWorker1.WorkerSupportsCancellation == true)
                {
                    // Cancel the asynchronous operation.
                    backgroundWorker1.CancelAsync();
                }
            }
    
            // This event handler is where the time-consuming work is done. 
            private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
            {
                BackgroundWorker worker = sender as BackgroundWorker;
    
                for (int i = 1; i <= 10; i++)
                {
                    if (worker.CancellationPending == true)
                    {
                        e.Cancel = true;
                        break;
                    }
                    else
                    {
                        // Perform a time consuming operation and report progress.
                        System.Threading.Thread.Sleep(500);
                        worker.ReportProgress(i * 10);
                    }
                }
            }
    
            // This event handler updates the progress. 
            private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
            {
                resultLabel.Text = (e.ProgressPercentage.ToString() + "%");
            }
    
            // This event handler deals with the results of the background operation. 
            private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
            {
                if (e.Cancelled == true)
                {
                    resultLabel.Text = "Canceled!";
                }
                else if (e.Error != null)
                {
                    resultLabel.Text = "Error: " + e.Error.Message;
                }
                else
                {
                    resultLabel.Text = "Done!";
                }
            }
        }
    }
    
    注意有些东西比较重要,比如WorkerReportsProgress要设置成true,你还要判断backgroundworker的isbusy属性是否是true。



    Barry
    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    2014年11月7日 10:01
    版主