Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/292.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用多线程实时更新DataGridVIew_C#_Multithreading_Datagridview - Fatal编程技术网

C# 使用多线程实时更新DataGridVIew

C# 使用多线程实时更新DataGridVIew,c#,multithreading,datagridview,C#,Multithreading,Datagridview,我有一个带有产品列表表的数据库 +----+-------------+-------+-------+ | id | description | price | Stock | +----+-------------+-------+-------+ | 1 | Item 1 | 1.50 | 5 | +----+-------------+-------+-------+ 然后我有一个双窗口窗体应用程序。每个应用程序都在单独的项目中 第一个应用程序是向表中插入一个数据

我有一个带有产品列表表的数据库

+----+-------------+-------+-------+
| id | description | price | Stock |
+----+-------------+-------+-------+
| 1  | Item 1      | 1.50  |   5   |
+----+-------------+-------+-------+
然后我有一个双窗口窗体应用程序。每个应用程序都在单独的项目中

第一个应用程序是向表中插入一个数据,该表查询“插入到产品列表描述、价格、股票价值”项目2',2.00,10。 第二个应用程序是使用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。

您可以使用控件的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();  
    }  
}

如果线程不是创建控件的线程,当尝试调用该控件时,调试器会引发InvalidOperationException,消息为control control name,该消息是从创建控件的线程以外的线程访问的。您不能直接这样做,当我关闭窗体时,您需要使用ControlInvokeRequired属性,它会给我ObjectDisposedException。@Ardian您可以参考此内容,非常感谢@Vandita:Cheers