简体   繁体   中英

c# how to use ProgressChanged event of BackgroundWorker to do UI actions in the middle of thread

Here is simple code which has UI actions in the middle of backgroundworker. There is a form and a label "lbProgress" on it. When ProgressPercentage = 2, label is not changed but the action does.

    private void Form1_Load(object sender, EventArgs e)
    {
        bw.WorkerSupportsCancellation = true;
        bw.WorkerReportsProgress = true;
        bw.DoWork += bw_DoWork;
        bw.ProgressChanged += bw_ProgressChanged;
        bw.RunWorkerCompleted += bw_RunWorkerCompleted;
    }
    int ii;
    private void bw_DoWork(object sender, DoWorkEventArgs e)
    {
        ii = 0;

        bw.ReportProgress(1);
        ii += 10;
        Thread.Sleep(1000);

        bw.ReportProgress(2); // here intended to do UI actions

        bw.ReportProgress(3);
        ii += 20;
        Thread.Sleep(1000);
    }
    private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        MessageBox.Show(ii.ToString());
    }
    private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        lbProgress.Text = e.ProgressPercentage.ToString();
        if (e.ProgressPercentage == 2)
        {
            this.Text += ", 00";
            ii += 100;
            Thread.Sleep(1000);
        }
    }

    private void btRun_Click(object sender, EventArgs e)
    {
        bw.RunWorkerAsync();
    }

Is it even possible to do large UI actions in the middle of backgroundworker thread using ProgressChanged event?

This is my answer to your question "Why do I see this behaviour?":

From the documentation of ReportProgress :

The call to the ReportProgress method is asynchronous and returns immediately.

So what happens is:

  • The BackgroundWorker calls ReportProgress(2)
  • The ProgressChanged event handler for progress 2 is started on the UI thread and blocks. The UI is not updated because the UI thread is blocked . (Hint: the screen is redrawn usually only when the UI thread is idle)
  • In the meantime, the BackgroundWorker has called ReportProgress(3)
  • The Blocked event handler finally finishes
  • The ProgressChanged event handler for progress 3 is run updating lbProgress.Text to "3" before your eyes had a chance to notice that it was "2" just a microsecond before (if it was rendered at all).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM