Link to home
Start Free TrialLog in
Avatar of RohitYadav
RohitYadav

asked on

Backgorund worker freezed the apllication

Hi,
First time i tried to use a background worker, to avoid the freezing while the information is processed.
That processing also involves populating two TreeViews. I am using Begin invoke for that. The delgate in its arguments calls a function which Populates the Trees.
As soon as the reaches Begin Invoke it freezes my application until the processing is done.
Can someone please guide me here, I am still new to threading and delegates.
Thanks

private void bWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            if (!bWorker.CancellationPending)
            {
 
                bWorker.ReportProgress(0);
                InitializeSmartUpdateSearh();
                 BeginInvoke(new MyDelegate(PopulateTreeNewProductLines),new object[]{tViewUpdatedProductLines, tViewNewProductLines});
                
            }
        }

Open in new window

Avatar of crazyman
crazyman
Flag of United Kingdom of Great Britain and Northern Ireland image

what does your PopulateTreeNewProductLines look like
Avatar of RohitYadav
RohitYadav

ASKER

Looks something like this. It calls a method PopulateUpdatesTree, which is in another class. Smhelper is a instance of that class.
private void PopulateTreeNewProductLines(TreeView tViewUpdatedProductLines, TreeView tViewNewProductLines)
        {
            try
            {
                Smhelper.PopulateUpdatesTree(tViewUpdatedProductLines, Smhelper.dtProductLineUpdates);
                Smhelper.PopulateUpdatesTree(tViewNewProductLines, Smhelper.dtNewProductLine);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

Open in new window

How it behaves when You replace BeginInvoke with Invoke?
Begin update and end update seems like it should work. i tried it but it gives me this error, this is code i am using.
"Action being performed on this control is being called from the wrong thread. Marshal to the correct thread using Control.Invoke or Control.BeginInvoke to perform this action."

I removed the begin invoke calls from my code. I am passing the TreeView as an argument in my RunAsync method.
private void bworker_DoWork(object sender, DoWorkEventArgs e)
        {
            if (!bworker.CancellationPending)
            {
                TreeView tV = (TreeView)e.Argument;
                bworker.ReportProgress(0);
                InitializeSmartUpdateSearh();
                bworker.ReportProgress(20);
                PopulateTree1(tV);
                bworker.ReportProgress(50);
 
            }
        }
 
        private void bworker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            if (e.ProgressPercentage == 20)
            {
                tViewNewProductLines.BeginUpdate();
            }
            else if(e.ProgressPercentage == 50)
            {
                tViewNewProductLines.EndUpdate();
            }
        }
 
        private void bworker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            DisplayUpdateWizardEnd();
        }
 
 
 
private void PopulateTree1(TreeView tViewNewProductLines)
        {
            try
            {
                Smhelper.PopulateUpdatesTree(tViewNewProductLines, Smhelper.dtNewProductLine);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

Open in new window

Why not use BeginInvoke to start the smHelper.Popuplate... method, and within that methid call BeginUpdate() and EndUpdate() at the begining and end.

Calling it in the progressChanged is not within the UI thread.
If i understand it right,  I need to call BeginUpdate() and EndUpdate() in the UI thread and the rest of the Tree processing between those 2 events in the worker thread right?
Consider this to be my PopulateTree method.
Can you show me with some code on how to make it work? I tried beginInvoke but it passes the whole job to the UI thread and my application freezes for sometime until the processing is done.


private void PopulateTree(TreeView tview)
{
   for(int x=0; x<1000; x++)
   {
      tview.Nodes.Add(i.ToString());
   }
}




Thanks
ASKER CERTIFIED SOLUTION
Avatar of crazyman
crazyman
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
or another option is to execute Populate procedure this in a worker thread

private void PopulateTree(TreeView tview)
{
   for(int x=0; x<1000; x++)
   {
     //BeginInvoke here  tview.Nodes.Add(i.ToString());
   }
}
That worked i had to invoke on  Treeview.Nodes.clear and TreeView.Nodes.Add .
Thanks for all who helped me.