当打开大量对话框时,我遇到了关闭程序的问题。我能够使用以下功能重现错误。运行它的父表单是使用Application.Run(mainform)创建的。
单击button1时,它会创建一个非常基本的表单,在按下“ok”时打开另一个自身对话框。然后它启动OnShutdown()函数。等待15秒,然后尝试关闭所有窗口并退出程序。当打开超过6个虚拟窗口时,该功能将关闭所有虚拟窗口,但不关闭主窗口。
我重现问题的步骤是:
15秒后,所有对话框都关闭,但父窗体仍然打开,应该关闭。
private void button1_Click(object sender,EventArgs e) {
BasicTemplate heavy = new BasicTemplate();
heavy.ShowDialog();
OnShutdown();
}
private void OnShutdown() {
timerSignals.Enabled=false;//quit receiving signals.
string msg = "";
msg+=Process.GetCurrentProcess().ProcessName+" ";
msg+=Lan.g(this,"will shut down in 15 seconds. Quickly click OK on any open windows with unsaved data.");
MsgBoxCopyPaste msgbox = new MsgBoxCopyPaste(msg);
msgbox.Size=new Size(300,300);
msgbox.TopMost=true;
msgbox.Show();
ODThread killThread = new ODThread((o) => {
Thread.Sleep(15000);//15 seconds
//Also happens with BeginInvoke()
Invoke((Action)(() => { CloseOpenForms(true); }));
Thread.Sleep(1000);//1 second
Invoke((Action)Application.Exit);
});
killThread.Start(true);
return;
}
public void Start(bool isAutoCleanup) {
_isAutoCleanup=isAutoCleanup;
if(_thread.IsAlive) {
return;//The thread is already running.
}
if(_hasQuit) {
return;//The thread has finished.
}
_dateTimeStart=DateTime.Now;
_thread.Start();
}
//Code for "OK" button on the heavy dialog created above
private void butOK_Click(object sender,EventArgs e) {
BasicTemplate formp = new BasicTemplate();
formp.ShowDialog();
}
private bool CloseOpenForms(bool isForceClose) {
for(int f=Application.OpenForms.Count-1;f>=0;f--) { //Count backwards to avoid out of bounds
if(Application.OpenForms[f]==this) {
continue;
}
Form openForm=Application.OpenForms[f];//Copy so we have a reference to it after we close it.
openForm.Hide();
if(isForceClose) {
openForm.Dispose();
}
else {
openForm.Close();//Attempt to close the form
if(openForm.IsDisposed==false) {
openForm.Show();//Show that form again
return false;
}
}
}
return true;
}
当第3行的“heavy.ShowDialog()”更改为“heavy.Show()”时,不再发生持有。当使用不同的按钮打开多个沉重的对话框时,不再出现问题(最多约20个新对话框)。
关闭序列作为线程运行,允许用户保存在程序数据库更新之前所做的任何更改。我不确定我实现的是否正确显示了错误,但它至少会产生类似的事件。