2017-04-05 21 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 :)干杯 –