1

请看这个:

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

- 结尾 -

全部在代码中,为什么需要更多的单词?全部在代码中,为什么需要更多的单词?全部在代码中,为什么需要更多的单词?

4

1 回答 1

1

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

所以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 窗体源代码,特别是以下几行:

于 2019-08-03T17:46:28.673 回答