后台工作者 运行 在 bw_DoWork() 和 bw_ProgressChanged() 上使用 textBox1.AppendText() 两次

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

我使用的是 Visual Studio 2013,我不明白为什么 bw_ProgressChanged() 在我使用 textBox1.AppendText() 时运行两次。 bw_DoWork() 也运行两次。

代码只是从 Microsoft example 复制粘贴,不同之处在于我使用 textBox1.AppendText() 而不是 textBox1.Text = ""

代码如下所示:

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!");
        }
    }
}

textbox1 文本 看起来像这样:

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!

而不是:

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

我试过将进度直接传递给局部变量,然后再传递给 textbox1,但没有任何区别。知道为什么会这样吗?

事件方法中的代码运行了两次,因为您以某种方式订阅了 ProgressChanged 事件两次。

因为我在你的代码中没有看到两个订阅,你可能已经通过设计器订阅了它(检查 Designer.cs 文件以确认),所以从构造函数中删除这一行:

bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);

同时,请仔细检查 DoWorkRunWorkerCompleted。您很可能也订阅了两次,这可以解释为什么您的输出打印 10 到 100,然后再次打印相同的双倍值。