C#,MessageBox后面的机制。显示
在Visual Studio C#中,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(
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是相关的,因此您无法实际看到它的功能。您不必实现自己的模态循环。您不应该依赖于任何模式循环的复杂行为,除非知道它将有一个消息循环,并且它会临时禁用父窗口。