Search code examples
c#backgroundworker

Background Worker Running Twice on bw_DoWork() and bw_ProgressChanged() when using textBox1.AppendText()


I'm using Visual Studio 2013 and I can't figure out why the bw_ProgressChanged() runs twice when I use the textBox1.AppendText(). Also the bw_DoWork() runs twice.

The code is just a copy paste from the Microsoft example with the difference that I'm using textBox1.AppendText() instead of textBox1.Text = "".

The code looks like this:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        bw.WorkerReportsProgress = true;
        bw.WorkerSupportsCancellation = true;
        bw.DoWork += new DoWorkEventHandler(bw_DoWork);
        bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);
        bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
    }

    private void button1_Click(object sender, EventArgs e)
    {
        if (bw.IsBusy != true)
        {
            bw.RunWorkerAsync();
        }
    }

    private void bw_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));
            }
        }
    }

    private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        this.textBox1.AppendText(e.ProgressPercentage.ToString() + "%\n");
    }

    private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        if ((e.Cancelled == true))
        {
            this.textBox1.AppendText("Canceled!");
        }

        else if (!(e.Error == null))
        {
            this.textBox1.AppendText("Error: " + e.Error.Message);
        }

        else
        {
            this.textBox1.AppendText("Done!");
        }
    }
}

The textbox1 text looks like this:

10%
10%
20%
20%
30%
30%
40%
40%
50%
50%
60%
60%
70%
70%
80%
80%
90%
90%
100%
100%
10%
10%
20%
20%
30%
30%
40%
40%
50%
50%
60%
60%
70%
70%
80%
80%
90%
90%
100%
100%
Done!Done!

Instead of:

10%
20%
30%
40%
50%
60%
70%
80%
90%
100%
Done!

I have tried to pass the progress directly to a local variable and then pass it to the textbox1 but it doesn't make any difference. Any ideas why this is happening?


Solution

  • The code inside the event method runs twice because you've somehow subscribed to the ProgressChanged event twice.

    Since I don't see two subscriptions in your code, you've probably subscribed to it through the designer (check the Designer.cs file to confirm), so remove this line from the constructor:

    bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);
    

    While you're at it, double-check DoWork and RunWorkerCompleted too. You're most likely subscribing to those twice as well, which would explain why your output is printing 10 through 100, and then printing the same doubled-up values again.