在应用程序失去焦点时解决崩溃问题

时间:2013-07-02 19:08:26

标签: c# winforms crash

我正在研究一个模拟代码,我有一个“项目”,可以进行大量的模拟。您可以选择一次运行一个,也可以按顺序运行它们。在这种特殊情况下,我有18个模拟逐个运行,整个过程大约需要20秒。

简而言之,在表单上按下按钮,会发生以下操作:

1)创建模拟对象
2)执行模拟启动命令
3)将模拟数据写入文件
4)配置模拟对象
5)更新保存模拟列表的DataGridView(将“Processing”重写为“Complete”)
6)更新用户控制中的进度条值 7)刷新用户控制。

粗略的源代码如下:

for (int i = 0; i < dataSet.Count; i++)
{
  using (Processor p = new Processor())
  {
    bool didTestPass = p.RunTest(dataSet[i]);

    if (didTestPass)
      dataGridViewProcessList.Rows[i].Cells[5].Value = "Run complete.";
    else
      dataGridViewProcessList.Rows[i].Cells[5].Value = "Run completed with errors.";
  }

  progressBarRuntime.Value = ((i+1) / dataSet.Count) * 100;

  this.Refresh();
  this.OnUpdateMainForm(this, null);
}

我发现,如果你仍然在应用程序的焦点范围内,所有18个模拟运行正常。但是,如果您放弃焦点(例如,切换到另一个程序),它在第8次模拟时始终表现不正常。我说的不规律,因为它的行为不同:

通过Visual Studio进行调试时,表单会暂时冻结,然后突然处理所有剩余的模拟,并且进度条会捕捉到完整。

当作为独立程序运行时,它会直接崩溃到桌面。没有警告,没有例外,一无所获。

我还发现,如果我保持专注并让它达到,例如,模拟14,然后从计划中删除焦点,它将立即表现出上述行为。

我对Windows窗体处于活动状态时执行大量计算工作的概念并不是特别熟悉。起初我觉得可能需要刷新表单(因为这一切都发生在UserControl上)但是当我发布一个强制表单Refresh()的事件时,我没有看到任何区别。

1 个答案:

答案 0 :(得分:0)

我最终发现我的问题的根源是我在界面的主线程上执行工作,结果导致我的程序挂起并崩溃到桌面。

我创建了BackgroundWorker并将我的工作代码放入DoWork事件中,然后将ProgressBar指标更新移至ProgressChanged事件中。

有关BackgroundWorker的详细信息及其在MSDN的实施情况。

简而言之,从我那里学到的教训是,如果表单中的活动花费的时间超过几秒钟,则应使用BackgroundWorker来完成,以防止挂起界面。