使用另一个线程将数据从数据库加载到组合框

时间:2012-03-31 14:33:53

标签: c# sql-server database winforms multithreading

我想在从数据库表中获取列后在组合框中添加项目。为了实现性能,我已将此任务放在新创建的线程中

for (int i = 0; i < dataTable.Rows.Count; i++)
{
    comboBox.Items.Add(dataTable.Rows[i][0].ToString());
}

但它给出了以下例外:

“跨线程操作无效”

我搜索了它,并尝试在不同的方法,代表的帮助下解决这个问题。我试图将整个dataTable传递给另一个方法,但无法解决问题。

请告诉我如何解决?

3 个答案:

答案 0 :(得分:3)

只需将代码包装在传递给BeginInvoke的代理中:

comboBox.BeginInvoke(
    (Action)(() =>
    {
       for (int i = 0; i < dataTable.Rows.Count; i++)
       {
          comboBox.Items.Add(dataTable.Rows[i][0].ToString());
       }
    }));

这样您就可以将更新转发到GUI线程,因为它是唯一允许在GUI上进行更改的线程。

答案 1 :(得分:0)

您可以(并且可能应该)在后台线程上运行数据库查询,但您必须更新UI线程上的UI控件。这就是Windows的工作方式。

答案 2 :(得分:0)

您的主题不是UI主题。只有UI线程可以像组合框一样访问UI控件 因此,更新组合框项目的方法应检查是否从UI线程调用它,如果没有,则在尝试使用组合框之前切换到该模式。

public delegate void OnAddTable(DataTable dataTable);

private void AddTable(DataTable dataTable)
{
    if(this.InvokeRequired) 
    {
        this.BeginInvoke(new OnAddTable(AddTable), new object[] {dataTable}));
        return;
    }
    for (int i = 0; i < dataTable.Rows.Count; i++) 
    { 
        comboBox.Items.Add(dataTable.Rows[i][0].ToString()); 
    }
}