简体   繁体   English

解决应用程序失去焦点时发生的桌面崩溃

[英]Resolving crash to desktop when application loses focus

I'm working on a simulation code where I have a "Project" which can hold numerous simulations. 我正在开发一个模拟代码,其中有一个“项目”,可以进行大量模拟。 You can choose to run them one at a time, or you can run them all in sequence. 您可以选择一次运行它们,也可以依次运行它们。 In this specific case, I have 18 simulations which run one by one, and overall the process takes about 20 sec. 在这种特定情况下,我有18个仿真,它们一个接一个地运行,整个过程大约需要20秒。

In short, a button is pressed on a form, and the following actions occur: 简而言之,在表单上按下一个按钮,就会发生以下动作:

1) Create simulation object 1)创建模拟对象
2) Perform simulation start command 2)执行模拟启动命令
3) Write simulation data to file 3)将模拟数据写入文件
4) Dispose simulation object 4)配置模拟对象
5) Update DataGridView which holds the simulation list (rewrites "Processing" to "Complete") 5)更新保存模拟列表的DataGridView(将“处理中”重写为“完成”)
6) Update progress bar value in user control. 6)更新用户控件中的进度条值。
7) Refresh user control. 7)刷新用户控件。

Rough source code is as follows: 粗糙的源代码如下:

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);
}

What I've found is, if you remain within the application's focus, all 18 simulations run fine. 我发现的是,如果您仍然处于应用程序的关注范围内,那么所有18个模拟都可以正常运行。 However, if you drop focus (say, switch to another program), it consistently behaves erratically at the 8th simulation. 但是,如果您放下焦点(例如,切换到另一个程序),则它在第8个模拟中的行为始终会不稳定。 I say erratically because it acts differently: 我之所以说是错误的,是因为它的行为不同:

When debugging through Visual Studio , the form freezes briefly, then suddenly all remaining simulations are processed and the progress bar snaps to full. 通过Visual Studio进行调试时 ,该表单将短暂冻结,然后突然处理所有剩余的模拟,并且进度条将变为完整状态。

When running as a standalone program , it crashes straight to desktop. 作为独立程序运行时 ,它直接崩溃到桌面。 No warning, no exception throw, nothing. 没有警告,没有抛出异常,什么都没有。

I've also found that if I stay focused and let it reach, say, simulation 14, then drop focus from the program, it will immediately exhibit the above behavior. 我还发现,如果我保持专注并让其达到模拟14, 然后将注意力从程序中删除,它将立即表现出上述行为。

I'm not particularly familiar with the concept of performing large calculation efforts under the hood while a Windows Form is active. 我对Windows窗体处于活动状态时在后台进行大量计算工作的概念并不特别熟悉。 At first I felt like maybe the Form needed to be refreshed (since this is all happening on a UserControl) but I saw no difference when I put in an event to force the Form to Refresh() . 起初,我觉得可能需要刷新Form(因为这都是在UserControl上发生的),但是当我放入一个将Form强制为Refresh()的事件时,我看不出有什么不同。

I ended up discovering that the source of my problem was that I was performing work on the interface's main thread, and as a result it was causing my program to hang and crash to desktop. 我最终发现问题的根源是我正在接口的主线程上执行工作,结果导致程序挂起并崩溃到桌面。

I created a BackgroundWorker and placed my work code into the DoWork event, then moved the ProgressBar indicator update into the ProgressChanged event. 我创建了BackgroundWorker ,并将工作代码放入DoWork事件中,然后将ProgressBar指示符更新移至ProgressChanged事件中。

More details regarding BackgroundWorker and its implementation at MSDN . 有关BackgroundWorker及其在MSDN上的实现的更多详细信息。

In short, the lesson learned for me is that if an activity in a Form is going to take longer than a few seconds, it should be done using a BackgroundWorker to prevent hanging up the interface. 简而言之,对我来说,教训是,如果Form中的活动要花费几秒钟以上的时间,则应该使用BackgroundWorker来完成该活动,以防止挂断界面。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM