Click here to Skip to main content
15,885,141 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
i have a datagridview and it take times to load it datasource . i want to make a loading for it and i tried background workers and async await and task.factory.startnew and task.run and ... but when datagridview is filling my loading gif will be freezed.

what should i do?

i googled a lot and i saw a text. they said we have just one ui thread and when one is working another will be freezed is that correct?

for example, it is like a situation that gif is loading and a richtextbox is filling:
pictureBox1 will be freezed when we are in huge function


C#
private  void  button1_Click (object sender, EventArgs e)
       {

         Task.Factory.StartNew(()=>;
         {
             huge();
         }
             );

       }


C#
private void huge()
        {
            richTextBox1.Invoke(new EventHandler(delegate
                {

              
                        for (int i = 0; i < 10000; i++)
                        {
                            richTextBox1.Text += "s";
                        }

                }));
            pictureBox1.Visible = false;
        }


What I have tried:

i tried background workers and async await and task.factory.startnew and task.run and ... but when datagridview is filling my loading gif will be freezed.
Posted
Updated 6-Nov-16 2:32am
Comments
Richard MacCutchan 6-Nov-16 8:06am    
The code you have shown has nothing to do with your question. Please show the actual code that is causing the problem. You may also like to explain what data you are using to fill the grid and where it comes from.

What is the number of records that you are trying to load in grid?

Did you consider paging the data like 10 or 20 records at a time?

I think in this case the loading of data should not require creating news threads.

Also from code posted: 'richTextBox1.Text += "s";' you should use StringBuilder for such task...code as is will create a new string each time.
 
Share this answer
 
Comments
Partogame 6-Nov-16 8:16am    
i have approximately about 6000 or 7000 records in my datatable.
is there any way to show them in just one page without freezing?
that string was just an example for showing freeze situation.
P_Z 6-Nov-16 8:23am    
Do you actually need to display all records?
Well no one needs to see all those records at time. Think of search engines, you don't get to see all the results on 1 page.
As mentioned you should use paging.

Also as you mention the "slowness" with 7K records...think of what would happen if there will be more records.
Partogame 6-Nov-16 8:34am    
i know what you have said, imagine a situation like that richtextbox(i just want to say a work like this, ui work &...).
what can i do?
imagine i have to show all of them. is there any way to show a loading image for user?
thanks for your response
You need to look at marshalling between your worker thread and the UI thread. The way your example would work is that the richtext will fill on the UI thread anyway. Granted, the updates of the richtext need to occur on the UI thread, but not the work of getting the data (the for loop). And finally, the setting of the picturebox's visible property needs to be marshalled back to the UI thread also.

Your huge method then becomes something like:

C#
for (int i = 0; i < 10000; ++i) {
    if (richTextBox1.InvokeRequired) {
       richTextBox1.BeginInvoke((MethodInvoker) delegate { richTextBox1.Text = richTextBox1.Text + "s"; });
    }
}


You'd probably want to speed up the action on the UI thread of appending the "s" to the RichTextbox as well. Get the initial value of the text at the start of huge(), append "s" to that on each loop, and then your delegate becomes { richTextBox1.Text = text; }.

The less work you can do on the UI, the more responsive it will become.
 
Share this answer
 
Comments
Partogame 6-Nov-16 9:09am    
that richtextbox was just an example.
this one " richTextBox1.Invoke(new EventHandler(delegate"
is exactly like "if (richTextBox1.InvokeRequired) {
richTextBox1.BeginInvoke((MethodInvoker) delegate { richTextBox1.Text = richTextBox1.Text + "s";"


"The less work you can do on the UI, the more responsive it will become."
this is write but my problem wasnt that richbox. i retrieve datatable from database with 6000 records and they should be bind to datagridview and this is taking much time
Midi_Mick 6-Nov-16 9:22am    
I realise it is just an example, but you are wrong about the "Invoke" being the same as the "BeginInvoke". Invoke actually waits for the message to be processed before proceeding. BeginInvode returns immediately, and only processes the delegate when the UI thread is available. Because you were invoking the delegate with the for loop in it, that for loop was being executed on the UI thread - locking everything else out.

For what you are actually doing, load the data in your background thread. Do not attempt to update anything while this is happening, unless you can do it with a very brief action. And if the update is not state-sensitive, use the BeginInvoke instead of the Invoke to do it. Then, once the load is complete, start updating the UI. If that, too, is a slow process, do it one bit at a time from a background thread, just Invoking the minimal update as necessary.

To get decent responsiveness, you need to fully separate your business logic from the UI. Partially separating them is often not enough.
Partogame 6-Nov-16 9:44am    
i did what you said for the example :
for (int i = 0; i < 10000; ++i)
{
if (richTextBox1.InvokeRequired)
{
richTextBox1.BeginInvoke((MethodInvoker)delegate { richTextBox1.Text = richTextBox1.Text + "s"; });
}
}
But again every thing is freezed.
Midi_Mick 6-Nov-16 11:30am    
Sorry - but that code is a bit on the messy side. You are probably going to have to tidy it up, and do bits of the code at a time to see where the bottleneck is.
What I would suggest is get rid of the Task - await - async altogether, and do all the business work in the background worker. Don't do any UI at all in that worker thread. Just set up the LCT, then the DataTable, and then return. Finally, in the BackgroundWorker.RunWorkerCompleted event, add your UI tasks one at a time (i.e.
DGV_ListEditCustomer.DataSource = table;
SetColumnsEditCustomerList();
See which of these 2 statements, if either, cause the hold-ups. I can't see the SetColumnsEditCustomerList method in your code there, but I am suspecting that that one is your culprit.
Partogame 6-Nov-16 9:48am    
and my real situation:
private async void BtnTabEditCustomer_Click(object sender, EventArgs e)
{
uiPBLoading.Visible = true;
await InitTabEditCustomerAsync();
uiPBLoading.Visible = false;

}
Task InitTabEditCustomerAsync()
{
return Task.Factory.StartNew(
() =>
{
Fill_EditCustomerList();
});

void Fill_EditCustomerList()
{
List<customer> LCT = new List<customer> { };
LCT = CustomerBR.GetCustomerList();

DGV_ListEditCustomer.SuspendLayout();
_bw_Fill_EditCustomerList.DoWork += new DoWorkEventHandler(bw_Fill_EditCustomerList);
_bw_Fill_EditCustomerList.RunWorkerAsync(LCT);

}

}
BackgroundWorker _bw_Fill_EditCustomerList = new BackgroundWorker();
void bw_Fill_EditCustomerList(object sender, DoWorkEventArgs e)
{

DataTable table = UtilHandler.ToDataTable((List<customer>)e.Argument);



DGV_ListEditCustomer.Invoke(new EventHandler(delegate
{
DGV_ListEditCustomer.DataSource = table;
SetColumnsEditCustomerList();
DGV_ListEditCustomer.ResumeLayout();

}));

}

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