C#,MessageBox后面的机制。显示

C#,MessageBox后面的机制。显示,c#,multithreading,modal-dialog,messagebox,autoresetevent,C#,Multithreading,Modal Dialog,Messagebox,Autoresetevent,在Visual Studio C#中,MessageBox.Show将停止但不锁定当前线程,直到消息窗口关闭 人们甚至可以把它放在if语句中,等待结果 为了理解它背后的机制,我试着做一个我自己的 假设有两个表单,MainForm和MsgFormMsgForm。您可以想象MsgForm是我的MessageBox.Show版本 键用于MainForm到等待MsgForm直到单击MsgForm中的按钮 也就是说,使其成为“模态” 我可以通过调用MainForm上的MsgForm.ShowDialog(

在Visual Studio C#中,
MessageBox.Show
将停止但不锁定当前线程,直到消息窗口关闭

人们甚至可以把它放在
if语句中,等待结果

为了理解它背后的机制,我试着做一个我自己的

假设有两个表单,
MainForm
MsgForm
<单击按钮时,会从
MainForm
调用code>MsgForm
。您可以想象
MsgForm
是我的
MessageBox.Show版本

键用于
MainForm
等待
MsgForm
直到单击
MsgForm
中的按钮

也就是说,使其成为“模态”

我可以通过调用
MainForm
上的
MsgForm.ShowDialog()
来管理它,因为
ShowDialog()
本身就是模态的

但后来我想,如果我没有内置的机制呢!?我怎么能做到同样的事

由于
Show()
不是模态的,所以我认为最好将其用于测试。如果我使用
Show()
停止了程序,那么我成功地重新创建了
MessageBox.Show

我第一次尝试在
MsgForm
上调用
AutoResetEvent.WaitOne()
,它锁定了整个事件!
MainForm
的结尾也是如此

但是后来我意识到必须在“不同的线程”上调用
WaitOne()
MsgForm
,以避免相互锁定

因此,我将以下代码放入
main表单中

private void button1_Click(object sender, EventArgs e)
{
    if(Test())
    {
        label1.Text = "Done!";
    }
}

private bool Test()
{
    Thread t = new Thread(doTest);

    t.Start();
    Class1.ARE.WaitOne();    //ARE is a public static AutoResetEvent in Class1 for global usages.
    return true;
}

private void doTest()
{
    MsgForm frm = new MsgForm();

    frm.Show();
}
只需调用
Class1.ARE.Set()
MsgForm
的按钮中单击事件

现在它不仅锁定了整个东西,而且还使
MsgForm
在“闪光”后消失

我在这里真是束手无策了

谁能告诉我哪里做错了


非常感谢

这是一个模态对话<代码>frm.ShowDialog()
以模式显示
frm
。粗略地说(我已经十多年没做win32编程了):虽然有一个模式对话框显示,但父窗口的消息循环一直在处理绘画消息,而不是键盘或鼠标消息。我在谷歌上搜索关于确切细节的文档,但结果是空的。如果你愿意,你可以随时查看源代码-@DetectivePikachu哇!这太棒了!谢谢我一定去看看
MessageBox.Show()
不会真正阻止线程。它阻止主消息泵对某些事件的处理(并自行启动)。这是相当复杂的,你自己去尝试会很疯狂。如果您想阻止最终用户在MsgForm可见时使用MainForm,您可以。Only是相关的,因此您无法实际看到它的功能。您不必实现自己的模态循环。您不应该依赖于任何模式循环的复杂行为,除非知道它将有一个消息循环,并且它会临时禁用父窗口。