【问题标题】:Show Loading animation during loading data in other thread在其他线程中加载数据期间显示加载动画
【发布时间】:2016-08-25 08:38:38
【问题描述】:

我有一个与数据库一起运行的应用程序。当我在 datagridview 中加载表时,我的表单冻结了。加载表格时如何保证加载动画流畅?

我为动画运行两个线程并将数据加载到表中,但动画仍然无法正常工作。

 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;
 }

【问题讨论】:

标签: c# .net multithreading winforms datagridview


【解决方案1】:

当窗体被冻结时,这意味着 UI 线程太忙,因此即使您尝试显示加载动画,它也不会动画。您应该异步加载数据。

您可以拥有一个返回Task<DataTable>async 方法,就像您可以在this post 中看到的GetDataAsync 方法一样。然后在async 事件处理程序中调用它。在事件处理程序中,首先显示加载图像,然后异步加载数据,最后隐藏加载图像。

您可以简单地使用显示 gif 动画的普通 PictureBox 作为加载控件。此外,您可能想查看this post 以显示透明的加载图像。

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();
}

【讨论】:

  • 我发现在我的示例和您的示例中,动画在dataGridView1.DataSource = data; 上冻结我可以await SQL 查询,但只要有对表单的引用,它的动画就会冻结。也许创建一个新的透明表单并在她身上显示动画?
  • 显示数据需要时间
  • 我使用了 100,000 条记录,延迟为 250-400 毫秒。如果要加载更多记录,最好重新考虑要显示数据的方式。您需要使用分页机制或在虚拟模式下使用数据网格视图并逐页显示数据。
  • 例如,我在每个页面中加载了 100,000 条记录中的 100 条记录,数据绑定大约需要 10 毫秒才能显示每个页面的数据。
  • 我相信对于当前的帖子,这是有用的答案。由于现在的问题是执行数据绑定时的延迟而不是加载数据时的延迟,因此我建议您根据此答案提出一个新问题。
猜你喜欢
  • 2010-12-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-25
  • 2013-06-12
  • 2019-09-04
  • 1970-01-01
相关资源
最近更新 更多