Show Loading animation during loading data in other thread

13,087

When the form is frozen, it means the UI thread is too busy and so even if you try to show a loading animation, it will not animate. You should load data asynchronously.

You can have an async method which returns Task<DataTable> like the GetDataAsync method which you can see in this post. Then call it in an async event handler. In the event handler, first show the loading image, then load data asynchronously and at last hide the loading image.

You can simply use a normal PictureBox showing a gif animation as loading control. Also you may want to take a look at this post to show a trasparent loading image.

enter image description here

public async Task<DataTable> GetDataAsync(string command, string connection)
{
    var dt = new DataTable();
    using (var da = new SqlDataAdapter(command, connection))
        await Task.Run(() => { da.Fill(dt); });
    return dt;
}

private async void LoadDataButton_Click(object sender, EventArgs e)
{
    loadingPictureBox.Show();
    loadingPictureBox.Update();
    try
    {
        var command = @"SELECT * FROM Category";
        var connection = @"Your Connection String";
        var data = await GetDataAsync(command, connection);
        dataGridView1.DataSource = data;
    }
    catch (Exception ex)
    {
        //Handle Exception
    }
    loadingPictureBox.hide();
}
Share:
13,087
DartAlex
Author by

DartAlex

Hey. My name is Sasha and I... I like "Star Wars", an interesting job and good music.

Updated on June 27, 2022

Comments

  • DartAlex
    DartAlex almost 2 years

    I have an application running with the database. When I load a tables in the datagridview, my form freezes. How to ensure the smooth load animation during loading tables?

    I run two threads for animation and load data into the tables, but the animation still does not always work.

     private volatile bool threadRun;
    
     private void UpdateTab()
     {      
         // Create panel for animation
         Panel loadingPanel = new Panel();              
         // Label, where the text will change
         Label loadingLabel = new Label();
         loadingLabel.Text = "Loading";        
    
         loadingPanel.Controls.Add(loadingLabel);
         this.Controls.Add(loadingPanel);
    
         // thread loading animation
         threadRun = true;         
    
         Task.Factory.StartNew(() =>
         {
             int i = 0;
             string labelText;
             while (threadRun)
             {
                 Thread.Sleep(500);
                 switch (i)
                 {
                     case 0:
                         labelText = "Loading.";
                         i = 1;
                         break;
                     case 1:
                         labelText = "Loading..";
                         i = 2;
                         break;
                     default:
                         labelText = "Loading...";
                         i = 0;
                         break;
                }
                loadingLabel.BeginInvoke(new Action(() => loadingLabel.Text = labelText));
             }
         });
    
         // thread update DataGridView   
         Thread update = new Thread(ThreadUpdateTab);
         update.Start();
     }
    
     private void ThreadUpdateTab()
     {
         // SQL Query...
         myDataGridView1.Invoke(new Action(() => myDataGridView1.DataSource = myDataSet1.Tables[0]));
         // ...
         myDataGridView10.Invoke(new Action(() => myDataGridView10.DataSource = myDataSet10.Tables[0]));
    
         threadRun = false;
     }
    
  • DartAlex
    DartAlex over 7 years
    I found that in my example and in your, animation freezes on dataGridView1.DataSource = data; I can await SQL-queries, but as soon as there is a reference to the form, it animation is froze. Maybe create a new transparent form and show animation on her?
  • DartAlex
    DartAlex over 7 years
    That display of data takes time
  • Reza Aghaei
    Reza Aghaei over 7 years
    I used 100,000 records and the delay was 250-400 milliseconds. If you want to load more records, it's better to rethink about the way you want to show data. You need to use a paging mechanism or using data grid view in virtual mode and show data page by page.
  • Reza Aghaei
    Reza Aghaei over 7 years
    For example, I showed 100 records of 100,000 records which I loaded in each page and data-binding took about 10 milliseconds to show data of each page.
  • DartAlex
    DartAlex over 7 years
    I load 10 DataGridView and during each display data - animation delay. In the case of one large table, your example is ideal.
  • Reza Aghaei
    Reza Aghaei over 7 years
    I believe for the current post, it's useful answer. Since the problem now is the delay when performing data-binding and not delay when loading data, I recommend you to ask a new question inspired by this answer.
  • Reza Aghaei
    Reza Aghaei over 7 years
    I can guess the answer for that question would be something like Since you should perform data-binding in UI thread, if the data-binding itself is time-consuming you should use a mechanism like paging.