Click here to Skip to main content
15,936,362 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more: , +
I am created an application where create more than 700 Labels in flowLayoutPanel. the creation process done in DoWork event of BackgroundWorker Class, but when the process started then the UI freeze.
I read and search all the tutorial about BackgroundWorker class and I follow the instruction, ultimately UI freeze when the Backgroundworker is in the processing.
My code is:

private void button1_Click(object sender, EventArgs e)
       {
           backgroundWorker1.RunWorkerAsync();
       }

       private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
       {
           List<Label> lblList = new List<Label>();
           for (int i = 1; i <= totaElement; i++)
           {
               Label lbl = new Label();
               lbl.Name = "lbl" + i;
               lbl.Text = i.ToString();
               lbl.BorderStyle = BorderStyle.FixedSingle;
               lbl.AutoSize = true;
               lblList.Add(lbl);
               backgroundWorker1.ReportProgress(i);
           }
           e.Result = lblList;
       }

       private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
       {
           int percentage = ((e.ProgressPercentage * 100) / 1000);
           progressBar1.Value = percentage;
       }

       private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
       {
           List<Label> CreatedLbl = (List<Label>)e.Result;
           flowLayoutPanel1.SuspendLayout();
           flowLayoutPanel1.Controls.AddRange(CreatedLbl.ToArray());
           flowLayoutPanel1.ResumeLayout();
       }


I download this[^] article's Demo and it's worked perfectly, but I couldn't find out my mistakes..

How to fix this problem?
How to free the UI ?
thanks in advanced..

Regards
Jayanta.
Posted
Updated 25-Jun-15 5:21am
v3
Comments
[no name] 25-Jun-15 11:27am    
"create more than 700 Labels", you really do not see the problem here?
JayantaChatterjee 25-Jun-15 11:33am    
I know that is big process, but that is in BackgroundWork class DoWork,
it suppose to not freeze the UI?
[no name] 25-Jun-15 11:43am    
It normally would not but you are doing UI work in your background thread! And, creating 700 labels tells everyone out here that you need to redesign your application. There is probably no reason at all for 700 labels to be created and shown to a user.
JayantaChatterjee 25-Jun-15 12:03pm    
I don't want to show the creation process to the user, Only I want to give the option to cancel the process. In this scenario the UI is freezed so user can not have that(Cancel) option..

My question is :
how to provide the cancel option to the user??
SteveHolle 25-Jun-15 12:26pm    
Where is the UI work in the background thread? I see loading a list and returning it on completion?

What nobody has said is that creating UI controls in a background thread is a horrible idea. Don't get into the habit of it. It may appear to work on the surface and in testing but your controls may not work properly.

UI controls should ALWAYS be created on the UI thread.

On top of that, creating 1000 labels is just going to kill your forms redraw performance.
 
Share this answer
 
Comments
JayantaChatterjee 27-Jun-15 5:25am    
thanks for suggestion..
I know this process(which I did) is not good for performance..
here I am making this application to doing some test with worker thread, so that's why I'm making this type of concept with Winforms controls..
most importantly I'm not include it with my habit.. :-)
Here is my final code:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {            
            for (int i = 1; i <= 1000; i++)
            {
                Label lbl = new Label();
                lbl.Name = "lbl" + i;
                lbl.Text = i.ToString();
                lbl.BorderStyle = BorderStyle.FixedSingle;
                lbl.AutoSize = true;
                lbl.BackColor = Color.LightSalmon;
                lbl.ForeColor = Color.DarkViolet;            
                Thread.Sleep(50);
                backgroundWorker1.ReportProgress(i,lbl);
            }            
        }

        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            int percentage = ((e.ProgressPercentage * 100) / 1000);
            progressBar1.Value = percentage;
            Label lbl =(Label) e.UserState;
            flowLayoutPanel1.SuspendLayout();
            flowLayoutPanel1.Controls.Add(lbl);
            flowLayoutPanel1.ResumeLayout();
        }


I changed the flowLayoutPanel1 update method, it updated on every Label creation on worker thread and also sending worker thread to sleep for 50 milliseconds(in the meantime the UI can update properly)..
and thanks to @F-ES Sitecore for the Idea...
 
Share this answer
 

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