除了调试时,应用程序挂在Control.Invoke上

时间:2014-04-10 07:47:19

标签: c# multithreading datagridview deadlock

我的主要表单使用Delegate.BeginInvoke启动了一些后台工作,在这些代理中我添加了一些行,以便在我的主窗体上的DataGridView上显示。我有一个支持数据集和一个附加BindingSource的数据集,我将其用作DataGridView的来源。

每当我添加一行时,我都这样做:

ResultsDataTable.AddResultsRow(row);
RefreshDataGridView();

RefreshDataGridView()看起来像这样:

private void RefreshDataGridView()
{
  if(InvokeRequired)
  {
    //I have tried dgvResults.Invoke() as well
    dgvResults.BeginInvoke(new Action(() => RefreshDataGridView()));
  }
  else
  {
    dgvResults.Refresh(); //this is where it hangs
    dgvResults.FirstDisplayedScrollingRowIndex = dgvResults.Rows.Count - 1;
  }
}

它运行良好,当我添加一个新行时,它立即显示并滚动(尽管我的滚动条没有正确绘制但我可以忍受),正如预期的那样,但只有当我通过调试器运行应用程序时。当我在没有调试的情况下启动它时,只要添加了一行并且实际上需要滚动它,应用程序就会挂起。

我已经在调试模式下构建了应用程序并在没有调试的情况下运行它,然后让它到达它挂起的位置并将调试器附加到进程以查看它发生的位置(请参阅上面的代码中的注释)。 / p>

我知道这种情况正在发生,因为我的主要线程正在等待某些东西,但我不知道它在等什么或如何找到它。

有没有人有任何想法?

更新:我在没有调试的情况下启动它,然后再次附加调试器,发现主线程卡住更新控件,但我无法弄清楚哪一个。

更新2:我摆脱了刷新,现在它在添加新行时没有挂起,但是如果没有挂起,我就无法调整表单大小。

更新3:在尝试更新数据网格的滚动条时似乎挂起了,所以我将其封装在一个面板中并改为给出了滚动条。通过一些黑客攻击来使数据网格根据其包含的数据动态调整自身大小,这有点毛病但没有更多的死锁。

1 个答案:

答案 0 :(得分:0)

我有同样的问题。您提到您的DataGridView附加了一个绑定源。如果您正在对源进行某些操作,那么您正在影响DataGridView。您需要将正在修改源代码的代码行放在BeginInvoke语句中。一旦我这样做,问题就消失了。