2017-04-05 57 views
0

我有數據庫與所屬類別表使用多線程的DataGridView的實時更新

+----+-------------+-------+-------+ 
| id | description | price | Stock | 
+----+-------------+-------+-------+ 
| 1 | Item 1  | 1.50 | 5 | 
+----+-------------+-------+-------+ 

然後,我有兩個Windows窗體應用程序。每個應用程序在單獨的項目上。

  1. 第一個應用是將數據插入到查詢爲INSERT INTO product_list (description, price, stock) VALUES ('Item 2', 2.00, 10)的表中。
  2. 第二個應用程序是使用datagridview實時查看錶。 我有一個對象爲我的數據庫,並有一個函數名GetTable()返回一個DataTable。

下面是返回DataTable的數據庫對象的代碼。

 public DataTable GetTable() 
    { 
     DataTable table = new DataTable(); 

     try 
     { 
      MySqlDataAdapter daTable = new MySqlDataAdapter(this.query, this.conn); 
      daTable.Fill(table); 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine(ex.ToString()); 
     } 

     return table; 
    } 

下面的代碼爲多線程

DataTable inventoryTable; 
    inventoryDB inventoryDB; 

    Thread updateDataGridView; 

    public Form1() 
    { 
     InitializeComponent(); 
     inventoryDB = new inventoryDB(); 
    } 

    private void Form1_Load(object sender, EventArgs e) 
    { 
     inventoryDB.SetQuery("SELECT id AS ID, description as Description, price as Price, stock as Stock FROM `product_list"); 
     inventoryTable = inventoryDB.GetTable(); 

     this.dataGridView1.DataSource = inventoryTable; 

     this.updateDataGridView = new Thread(new ThreadStart(this.RealTimeData)); 
     this.updateDataGridView.Start(); 
    } 

    private void RealTimeData() { 
     while (true) { 
      testTable = inventoryDB.GetTable(); 

      this.dataGridView1.DataSource = testTable; 
      this.dataGridView1.Update(); 
      this.dataGridView1.Refresh(); 
     } 
    } 

當我運行Visual Studio提供一個InvalidOperationException異常。

+0

比創建的控制時試圖調用該控制所述一個其他線程時,調試器提高與消息一個InvalidOperationException,「控制控制名從比上創建的線程以外的線程訪問」。你不能直接這樣做,你需要使用控制 – Vandita

回答

1

您可以使用控件的InvokeRequired屬性。試試這個代碼。

DataTable inventoryTable; 
inventoryDB inventoryDB; 

Thread updateDataGridView; 

public Form1() 
{ 
    InitializeComponent(); 
    inventoryDB = new inventoryDB(); 
} 

private void Form1_Load(object sender, EventArgs e) 
{ 
    inventoryDB.SetQuery("SELECT id AS ID, description as Description, price as Price, stock as Stock FROM `product_list"); 
    inventoryTable = inventoryDB.GetTable(); 

    this.dataGridView1.DataSource = inventoryTable; 

    this.updateDataGridView = new Thread(new ThreadStart(this.RealTimeData)); 
    this.updateDataGridView.Start(); 
} 

private void RealTimeData() { 
    testTable = inventoryDB.GetTable(); 
    this.SetDataSourceInGridView(testTable); 
} 

// This delegate enables asynchronous calls for setting 
// the datasource property on a GridView control. 
delegate void GridViewArgReturningVoidDelegate(DataTable testTable); 

private void SetDataSourceInGridView(DataTable testTable) 
{ 
    // InvokeRequired required compares the thread ID of the 
    // calling thread to the thread ID of the creating thread. 
    // If these threads are different, it returns true. 
    if (this.dataGridView1.InvokeRequired) 
    {  
     GridViewArgReturningVoidDelegate d = new StringArgReturningVoidDelegate(SetDataSourceInGridView); 
     this.Invoke(d, new object[] { testTable }); 
    } 
    else 
    { 
     this.dataGridView1.DataSource = testTable; 
     this.dataGridView1.Update(); 
     this.dataGridView1.Refresh(); 
    } 
} 
+0

的InvokeRequired屬性,當我關閉窗體它給我ObjectDisposedException。 –

+0

@Ardian你可以參考這個http://stackoverflow.com/questions/19619966/exception-when-closing-form-thread-invoke – Vandita

+0

非常感謝@Vandita :)乾杯 –