0

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?

Orgil
  • 187
  • 3
  • 13
  • 4
    Why do you want to Sleep in `bw_ProgressChanged` (on the UI Thread)? – Klaus Gütter Jul 09 '22 at 07:35
  • 1
    Yeah, sleeping in the `ProgressChanged` event handler makes no sense at all. You should read [this](https://www.vbforums.com/showthread.php?542316-Using-the-BackgroundWorker-Component). – user18387401 Jul 09 '22 at 09:18
  • @KlausGütter: sleep is just for long actions, just to make sure lbProgress.Text is changing. Main problem is, no matter what there is sleep or actual long actions, lbProgress.Text = 2 is not showing. 1 and 3 is ok, but 2 does not show. Why?. Seems like ProgressChanged event not fully works on UI actions. And I don't understand and searching for help! – Orgil Jul 10 '22 at 04:52

1 Answers1

2

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).
Klaus Gütter
  • 11,151
  • 6
  • 31
  • 36
  • Thanks for the answer. Now I understood what ProgressChanged event is. Very10000 much thank you! – Orgil Jul 12 '22 at 04:05