2012-08-15 94 views
1

此代码允许在加载数据之前加载表单,但在加载数据之前,表单上的某些组件(如按钮和datagridview本身)是“不可见”的。将数据异步加载到数据网格视图中的最佳方式是什么?

我该如何解决这个问题?

private void Form1_Load(object sender, EventArgs e) 
    { 
     Thread t = new Thread(new ThreadStart(delegate() 
     { 
      this.Invoke(new MyDelegate(delegate() 
      {    
       ReadXml(path); 
       Bind(); 
      }));    
     })); 

     t.Start(); 
    } 

    private void Bind() 
    { 
     dataGridView1.DataSource = table; 
    } 

我也有这个其他代码更好,但要求我使用2个新线程。这不可能是做到这一点的最佳方式,可以吗?

private void Form1_Load(object sender, EventArgs e) 
    { 
     Thread t = new Thread(new ThreadStart(delegate() 
      { 
       this.Invoke(new InvokeDelegate(delegate() 
       { 
        Thread t2 = new Thread(new ThreadStart(delegate() 
        { 
         ReadXml(path); 
        })); 
        t2.Start(); 
        t2.Join(); 
        Bind(); 
       })); 
      })); 

     t.Start(); 
    } 
+1

如果这是在表单加载时运行的* only *代码,那么所有代码​​都应该完美并且流畅地运行,imo。在这一点上,有些东西阻碍了你的用户界面。检查出来...... – Tigran 2012-08-15 20:06:46

+0

**或**我看到'Bind()'方法,如果该方法实际上将数据放在UI上,* *可能是阻塞调用。 – Tigran 2012-08-15 20:07:22

+0

这就是我在Form1_Load事件处理程序过程中的所有内容。绑定()只是这样做:dataGridView1.DataSource = table; – 2012-08-15 20:12:29

回答

1

如果使用BeginInvoke()而不是Invoke(),委托中的代码将在当前UI线程上执行,但直到所有当前UI工作待处理完成(如当前的Form1_Load调用)之后才会发生。 Invoke是一个同步调用,所以这就是为什么你需要这个线程。

void Form1_Load(object sender, EventArgs e) 
    { 
     this.BeginInvoke(new MyDelegate(delegate() 
     { 
      ReadXml(path); 
      Bind(); 
     })); 
    } 
+0

尽量为您的答案提供一些解释,而不是仅提供一个代码块。它将帮助其他用户了解答案,而不是纠正本地化问题。谢谢! – Conner 2012-08-16 04:27:20

+0

好点,我没有打扰,因为它在上面的评论,但我可以看到有人不会钻到他们的位置 – 2012-08-16 15:20:57

2

表单计时器(不是系统计时器)会让所有其他消息在触发前处理。

只要给它一个100-250毫秒的间隔; 在设计器中将其设置为enabled = false; 在form_load事件中将其设置为enabled = true。 在timer_tick事件中,使第一行timer.enabled = false。 之后(仍然在滴答事件)加载您的网格。

+0

这看起来像一个黑客,但至少它的作品。你赢了。 – 2012-08-15 20:27:41

相关问题