C# 如何使用线程来更新一个数据表,该数据表倾向于通过主线程进行动态更改?

C# 如何使用线程来更新一个数据表,该数据表倾向于通过主线程进行动态更改?,c#,winforms,C#,Winforms,有一个数据表,用于在单击按钮时填充,如“搜索”。在此按钮上,单击dataTable填充数据时。我正在创建一个新线程,该线程在dataTable数据更新。但用户再次点击了搜索按钮。现在,当线程已经在更新该数据表时,该数据表再次填充了新数据。在搜索时,再次单击代码创建一个新线程,并开始更新已更改的数据表。我在这里遇到错误:跨线程操作无效:从创建控件“”的线程以外的线程访问该控件“”。请提出解决办法。谢谢您可以将搜索按钮分配给 btn.Enabled = false; 当单击它并调用方法时,将在搜索

有一个数据表,用于在单击按钮时填充,如“搜索”。在此按钮上,单击dataTable填充数据时。我正在创建一个新线程,该线程在dataTable数据更新。但用户再次点击了搜索按钮。现在,当线程已经在更新该数据表时,该数据表再次填充了新数据。在搜索时,再次单击代码创建一个新线程,并开始更新已更改的数据表。我在这里遇到错误:跨线程操作无效:从创建控件“”的线程以外的线程访问该控件“”。请提出解决办法。谢谢

您可以将搜索按钮分配给

btn.Enabled = false;
当单击它并调用方法时,将在搜索结束时重新启用它

如果不想禁用按钮,可以使用此代码

private BackgroundWorker trd;

private void button1_Click(object sender, EventArgs e)
{
   if (trd != null)
   {
      trd.CancelAsync();
   }

   trd = new BackgroundWorker();
   trd.DoWork += new DoWorkEventHandler(trd_DoWork);
   trd.WorkerSupportsCancellation = true;
   trd.RunWorkerAsync();
}

public void trd_DoWork(object sender, DoWorkEventArgs e)
{
     // Your search code
}
这样就可以中止线程并重新启动它。搜索在中间停止,不会使用其他后台工作程序编辑值。后台工作程序正在编辑这些值,这意味着不会有交叉线程,因为您知道除了UI线程之外,没有其他线程可以编辑UI

  • 检查您正在更新的控件上是否需要Invoker,然后在必要时进行Invoke或BeginInvoke
  • 禁用按钮和/或禁用新更新(如果更新已在进行中)
  • 要更新DataGridView的数据源,请执行以下操作:

    if(DGV.InvokeRequired)
    DGV.Invoke(new EventHandler(delegate
    {
         DGV.DataSource= currentDataTable;
    }));
    else DGV.DataSource= currentDataTable;
    

    如果您正在从另一个线程更新并设置CurrnDATABATE,那么您应该考虑创建一个事件,当您的更新完成后(或完成工作-如果您使用后台工作人员),该事件将触发并更新您的GUI。-那么调用就没有必要了。

    好吧,但是如果我不想让用户通过禁用搜索按钮来限制,比如说,我希望上一个线程停止和新线程在新更新的数据表上工作,那该怎么办?嗨@不知道名称,非常感谢。这对我有用。但我的问题是不同的,因为即使在实现了上述代码之后,我也遇到了同样的问题,但在分析代码之后,我发现了一行,在该行中,每当我更新该数据表中的一行时,我都会引用网格。当我拆下那条线的时候。很好用。嗨@Arie,谢谢你的建议。在我的例子中,我正在更新的控件是DataTable。你能给我一个代码示例吗?你有任何数据绑定集可以将你的数据表绑定到你的控件上吗?根据我的经验,当您尝试从UI线程以外的线程更新某些UI元素时,通常会引发此异常(意味着您的后台线程以某种方式(直接或间接)尝试更改UI)是的,dataTable是网格控件的数据源,我正在另一个线程中更新该dataTable的数据,而网格控件已由主线程分配dataTable作为数据源。