【问题标题】:Real Time Update of DataGridVIew using Multithreading使用多线程实时更新 DataGridVIew
【发布时间】:2017-04-05 05:47:08
【问题描述】:

我有一个带有 product_list 表的数据库

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

然后我有一个两个窗口窗体应用程序。每个应用程序都在单独的项目中。

  1. 第一个应用程序是将数据插入到查询为INSERT INTO product_list (description, price, stock) VALUES ('Item 2', 2.00, 10) 的表中。
  2. 第二个应用是使用datagridview实时查看表格。 我的数据库有一个对象,并且有一个返回 DataTable 的函数名称 GetTable()。

这是返回 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。

【问题讨论】:

  • 在尝试调用该控件时创建控件的线程以外的线程,调试器引发 InvalidOperationException 并显示消息“从创建它的线程以外的线程访问的控件控件名称。”您不能直接这样做,您需要使用控件的 InvokeRequired 属性

标签: c# multithreading datagridview


【解决方案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();  
    }  
}

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2013-11-04
  • 1970-01-01
  • 1970-01-01
  • 2018-11-26
  • 2015-08-03
  • 2011-02-05
  • 1970-01-01
  • 2010-12-12
相关资源
最近更新 更多