2016-08-25 135 views
1

我有一个应用程序与数据库一起运行。当我在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; 
} 
+0

为什么线程和任务的组合?选择一个,而不是两个。选择TPL,恕我直言。 – Maarten

+0

看看[在Windows窗体中将数据异步加载到我的DataTable中](http://stackoverflow.com/a/38427392/3110834)。 –

+0

此外,如果您可能有兴趣[显示透明加载微调高于其他控件](http://stackoverflow.com/a/37473192/3110834) –

回答

2

当表单被冻结,这意味着UI线程是太忙,所以即使你试图表明加载动画,它不会动画。您应该异步加载数据。

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

您可以简单地使用正常的PictureBox显示gif动画作为加载控件。你也可以看看this post显示一个透明的加载图像。

enter image description here

public async Task<DataTable> GetDataAsync() 
{ 
    var dt = new DataTable(); 
    var cn = @"Your Connection String"; 
    var cmd = @"SELECT * FROM Category"; 
    var da = new SqlDataAdapter(cmd, cn); 
    await Task.Run(() => { da.Fill(dt); }); 
    return dt; 
} 

private async void LoadDataButton_Click(object sender, EventArgs e) 
{ 
    loadingPictureBox.Show(); 
    loadingPictureBox.Update(); 
    try 
    { 
     var data = await GetDataAsync(); 
     dataGridView1.DataSource = data; 
    } 
    catch (Exception ex) 
    { 
     //Handle Exception 
    } 
    loadingPictureBox.hide(); 
} 
+0

我发现在我的示例中,动画冻结了dataGridView1.DataSource = data;我可以等待SQL查询,但只要有对表单的引用,它动画冻结了。也许创建一个新的透明表单并在她身上显示动画? – DartAlex

+0

数据显示需要时间 – DartAlex

+0

我使用了100,000条记录,延迟时间为250-400毫秒。如果您想要加载更多记录,最好重新考虑想要显示数据的方式。您需要在虚拟模式下使用分页机制或使用数据网格视图,并逐页显示数据。 –