4

所以在过去的一天左右,我一直在修复一个由模式对话框引起的错误。我在一个通过 Windows 消息泵与服务器通信的应用程序上工作。当我使用 ShowDialog() 显示模态表单时,消息泵被阻止并且我的任何消息都没有被处理,但它们确实在队列中建立(预期行为)。

但是,我最近注意到,如果通过菜单项的单击事件打开模式窗体,则消息将被泵送到主窗体并进行处理。有谁知道为什么当通过菜单项的单击事件显示模态表单时这些消息没有被阻止?

编辑:我应该注意到我正在使用 C#。这个怎么样; 如果没有人能回答这个问题,谁能告诉我如何自己调查这个问题?我唯一能想到的就是查看调用堆栈。不幸的是,这还没有告诉我任何事情。

4

7 回答 7

1

是的,我从菜单项的单击事件中调用 ShowDialog()。在这种情况下,消息通过模态对话框泵送到主窗体。

于 2008-09-25T23:22:59.097 回答
1

尝试将菜单中的对话框设置为相同的所有者/父对象,以显示预期的消息泵送行为。

于 2008-11-07T16:34:03.697 回答
1

通常,您的客户端 UI不应因长时间的服务器操作而阻塞。.Net 使得使用 BackgroundWorker 线程进行服务器工作变得非常容易。有关示例,请参见此帖子:多线程导入

该示例在 VB 中,但您可以点击 C# 示例的链接。

于 2009-02-04T05:45:47.230 回答
0

您是从单击事件中调用 ShowDialog() 还是以其他方式调用?

于 2008-09-25T23:09:48.537 回答
0

您使用的是哪种菜单控件?它可以在与主窗体运行的线程不同的线程上运行吗?

于 2008-09-26T01:06:18.427 回答
0

@Chris: I am just using the standard MenuStrip control. If it were running on a separate thread, I would then be interested in how it shows the form as modal. I experimented with showing the dialog from a separate thread as to not block the message queue, but I cannot specify the main form as a parent, so it is not really modal.

于 2008-09-26T01:23:15.720 回答
0

我不清楚您所说的“消息泵被阻止”是什么意思。

发生的情况是 ShowDialog 没有返回,因此顶级消息泵正在等待您的应用程序从处理使其调用 ShowDialog 的任何事件返回;这与您的处理程序甚至在磨削 CPU 没有什么不同。所以,是的,从这个意义上说,消息泵被阻塞了。

但是模态对话框本身运行自己的消息泵循环,直到对话框关闭,它应该像主循环一样处理消息,所以我不明白为什么任何消息都应该在队列中建立。

这个消息循环处理所有窗口的消息,因为它必须例如允许应用程序的其他窗口正确地绘制自己。

您可能会尝试查看回调堆栈(从 ShowDialog 调用向下到堆栈的根),并比较“事情正常工作”和“事情不工作”时的外观。这可能有点微妙,比如您是通过消息调度还是消息预处理来调用 ShowDialog(我刚刚发现当您调用 ContextMenuStrip.Show 时会有所不同)

于 2021-11-25T17:42:27.160 回答