look this please:
var form = new Form();
form.Shown += (_, __) =>
{
var timer = new System.Windows.Forms.Timer { Interval = 1000 };
timer.Tick += (x, xx) =>
{
timer.Stop();
GC.KeepAlive(timer);
timer.Dispose();
form.Close();
Application.DoEvents(); // no effect
// it will cause form keep show
MessageBox.Show("asdf");
// but if this, that's fine
// BeginInvoke(new Action(() => MessageBox.Show("asdf")));
};
timer.Start();
};
form.ShowDialog();
form.Close before MessageBox.Show, but form will not close until close msgBox, please help.
--end--
all in code, why need more words? all in code, why need more words? all in code, why need more words?
When you show a form as modal using
ShowDialog(), callingClosein fact sends aWM_CLOSEmessage and then it setsDialogResulttoCancelwhich acts as a flag for modal message loop to exit the loop.So
Closewill not close or hide the modal dialog immediately. Then after finishing the modal message loop, the modal dialog will be hide (but not destroyed).MessageBoxmethod also blocks the execution of code, so codes after the message box will execute just after closing the message box. So now it's clear why after callingClose, first theMessageBoxshows then after closing message box, form closes.Just to make it easier to understand, here is a pseudo-code which shows what is happening when you call
ShowDialogin your code:Just keep in mind,
Closeis not equal toreturn, it means the code which you have afterClosewill run as well. Here the code isMessageBoxwhich blocks the loop until afterMessageBoxcloses.To hide the dialog immediately, replace the
form.Close()withform.Hide(), this way without waiting for the loop, you are commanding the form to get hidden. But it doesn't mean theformhas been closed and therefore lines of code which you have afterShowDialogwill not run until after the loop finishes.For more information about how
CloseandShowDialogwork, you may want to take a look at a Windows Forms source code, specially the following lines:LocalModalMessageLoopinApplicationCheckCloseDialoginFormWMCloseinForm