【问题标题】:SendMessage(HWND_BROADCAST, ....) hangsSendMessage(HWND_BROADCAST, ....) 挂起
【发布时间】:2009-12-23 09:35:18
【问题描述】:

当我将SendMessage 函数与HWND_BROADCAST 一起使用时,应用程序挂起。应用长时间没有响应。

谁能解释一下原因?

【问题讨论】:

    标签: windows winapi


    【解决方案1】:

    当有一个进程具有顶级窗口,但没有在创建窗口的线程上调用 GetMessage 或 PeekMessage 时,就会发生这种情况。

    为了向后兼容 Windows 3.0,SendMessage 在系统中的所有顶级窗口都响应您的广播之前不会返回。这种行为在 Windows 多线程之前是有意义的,因为 SendMessage(),即使发送到其他进程也永远不会阻塞。

    但是从 Win32 开始,当您向另一个进程中的窗口发送消息时,实际发生的是您的线程阻塞,直到另一个进程中的线程唤醒并处理消息。如果该线程很忙,或者只是没有发送消息,那么您将永远等待。

    因此,当您使用 HWND_BROADCAST 或向其他进程拥有的窗口发送消息时,您应该始终使用 SendNotifyMessageSendMessageTimeout

    【讨论】:

      【解决方案2】:

      这是因为当用HWND_BROADCAST 调用SendMessage 时,它首先枚举所有可用的窗口,然后为每个窗口调用SendMessageSendMessage 在窗口完成处理消息之前不会返回。如果单个窗口处理消息的时间过长,整个调用都会被延迟。

      【讨论】:

      • 更糟糕的是,如果一个被调用的窗口过程never 也不会返回 SendMessage(),并且应用程序将永久挂起。一般来说,您无法知道另一个应用程序的窗口将如何响应任意消息(即使是使用 RegisterMessage() 创建的消息)。简而言之,除非您确切知道该窗口是什么以及它将如何响应,否则您永远不应该调用 SendMessage() 向窗口发送消息。
      【解决方案3】:

      有一个 SendMessageTimeout 将限制您的应用程序在等待接收方接受时阻塞的时间。

      另一种解决方法是启动多个线程并让它们同时传递多条消息(即并行发送给它)。然后,如果其中一个接收器挂起,您不会杀死整个应用程序。

      【讨论】:

        【解决方案4】:

        至少有一个进程具有消息泵但不泵送消息。 SendMessage 在所有接收者都处理完消息之前不会返回......所以它不会返回。您可以尝试使用 SendMessageTimeout 来解决此问题。

        顺便说一句,这就是为什么启动一个进程并等待它的进程句柄会充满问题。我在我的网站here 上对此进行了描述。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-09-09
          • 1970-01-01
          • 2011-09-07
          • 2023-03-30
          • 1970-01-01
          • 2011-03-06
          相关资源
          最近更新 更多