为什么 Form.Close 等待 MessageBox.Show?

Why Form.Close wait MessageBox.Show?

请看这个:

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.CloseMessageBox.Show 之前,但是 form 在关闭 msgBox 之前不会关闭,请帮忙。

--结束--

都在代码里,何必多说几句?全部在代码中,为什么需要更多的文字?全部在代码中,为什么需要更多的文字?

当您使用 ShowDialog() 将表单显示为模态时,实际上调用 Close 会发送 WM_CLOSE 消息,然后将 DialogResult 设置为 Cancel它充当模态消息循环退出循环的标志。

因此Close不会立即关闭或隐藏模态对话框。然后在完成模态消息循环后,模态对话框将被隐藏(但不会被破坏)。

MessageBox方法也会阻塞代码的执行,所以消息框后面的代码会在消息框关闭后立即执行。所以现在很清楚为什么在调用 Close 之后,首先显示 MessageBox 然后在关闭消息框后关闭表单。

为了更容易理解,下面是一段伪代码,它显示了当您在代码中调用 ShowDialog 时发生的情况:

Form Shows
While Form.DialogResult != None
{
    Form.Close → Sends WM_CLOSE → Sets Form.DialogResult = Cancel 
    MessageBox.Show and wait until MessageBox closes
}
Form Hides

请记住,Close 不等于 return,这意味着您在 Close 之后的代码也将 运行。这里的代码是 MessageBox,它会阻塞循环直到 MessageBox 关闭。

要立即隐藏对话框,请将 form.Close() 替换为 form.Hide(),这样无需等待循环,您就可以命令表单隐藏。但这并不意味着 form 已经关闭,因此在 ShowDialog 之后的代码行不会 运行 直到循环结束。

有关 CloseShowDialog 如何工作的更多信息,您可能需要查看 Windows 表单源代码,特别是以下几行: