2012-08-15 13 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

相關問題