Click here to Skip to main content
15,916,463 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
Background Worker doesn't work. still hangs the UI.

Even Progress report doesn't reflect in progress bar.

C#
private void cmdStartUtility_Click(object sender, EventArgs e)
       {
          backgroundWorker.RunWorkerAsync();
       }


C#
private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
       {

           this.Invoke(new Action(() =>
           {

               for (int i = 0; i < 100;i++ )
               {
                   Thread.Sleep(1000);
                   backgroundWorker.ReportProgress(i);
                   txtLog.Text = i.ToString();
               }

                   backgroundWorker.ReportProgress(100);
           }));
       }


C#
private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
       {
           progressBar1.Value = e.ProgressPercentage;
       }
Posted
Comments
Mehdi Gholam 11-May-15 2:34am    
Why the Invoke() and new Action() ?
Sergey Alexandrovich Kryukov 11-May-15 2:43am    
"Why Invoke?" is a correct question, but "why new Action" is not — this is how Invoke is used. Of course, using Invoke is the total absurd. I'll answer the question, please see.
—SA

I haven't seen so much of absurd for a long time. You create a separate thread and then invoke all its code back to the UI thread. All code executed on the non-UI thread should not be under Invoke or BeginInvoke. You should use these methods only in some quickly executed actions which do something to the UI.

Please see my past answer and my other answers referenced in this one: .NET event on main thread[^].

—SA
 
Share this answer
 
Comments
Mehdi Gholam 11-May-15 2:50am    
Yes exactly! and if you need to update the UI then use ReportProgress() that's what it is there for.

5'ed
Sergey Alexandrovich Kryukov 11-May-15 2:59am    
Thank you, Mehdi.
—SA
Shmuel Zang 11-May-15 4:05am    
5'ed. It really looks strange to create a worker thread and, run the whole of its code in the UI thread. :)
Sergey Alexandrovich Kryukov 11-May-15 10:21am    
Thank you, Shmuel.
—SA

I guess you work with WinForms. The Invoke method lets you to run code in the UI thread. But, why do you run the whole of the worker's code (including the Sleep statement that blocks...) in the UI thread? Try to run only the progress change using the Invoke method. Try to remove the Invoke call from DoWork and, move the whole of the UI changes to the backgroundWorker_ProgressChanged method (see the comment below). Something like:


C#
private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
       {
               for (int i = 0; i < 100;i++ )
               {
                   Thread.Sleep(1000);
                   backgroundWorker.ReportProgress(i);                   
               }
 
               backgroundWorker.ReportProgress(100);
       }

private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
       {
           txtLog.Text = e.ProgressPercentage.ToString();
           progressBar1.Value = e.ProgressPercentage;
       }
 
Share this answer
 
v3
Comments
Sascha Lefèvre 11-May-15 14:31pm    
Sorry Shmuel, I had to vote 1: The ProgressChanged-eventhandler is automatically executed on the UI-thread. No invoking neccessary there (likewise the RunWorkerCompleted-eventhandler). Only in DoWork(..) it's neccessary to use Invoke for accessing the UI. And 'txtLog' looks like a TextBox, so setting its .Text-property should either be done via Invoke in DoWork() or moved to ProgressChanged(..). I will reconsider my vote if you improve your answer.
/Sascha
Shmuel Zang 12-May-15 3:11am    
I accept the comment. I changed the solution appropriately.
Sascha Lefèvre 12-May-15 7:06am    
Very well, my 5 :)
Shmuel Zang 12-May-15 7:45am    
Thanks.
George Swan 12-May-15 14:24pm    
If possible, I'd use the Task Parallel Library (TPL) rather than the Background worker class. It's cleaner and more simple to set up.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900