gpt4 book ai didi

multithreading - 使用 TSaveDialog 了解应用程序线程消息丢失的原因

转载 作者:行者123 更新时间:2023-12-03 15:08:50 36 4
gpt4 key购买 nike

使用 RAD Studio (Delphi) v10.2.1 进行开发(东京版本 1)在 Windows 10“创意者更新”64 位上,但进行 32 位开发。

该应用程序是具有多个后台线程的 VCL,每个线程都使用 Indy TidHTTP 来获取网络资源。主线程和后台线程之间的同步是使用消息队列(PostThreadMessage 调用)实现的。这已经足够复杂了,在这里提供直接代码会很困难而且很困惑,所以我从口头描述开始。

应该发生什么:打开一个包含外部资源链接的文件,这会生成 HTTP 请求并将它们交给后台处理,然后等待应用程序消息队列上的传入消息,表明资源已下载。应用程序消息与分配给 TApplication.OnMessage 的事件代码相匹配(我怀疑这就是我的问题所在)。

它有效。大多数时候一切都很顺利。但是,如果我打开 TSaveDialog - 即使我取消对话框而不是实际执行任何操作 - 那么消息就会从应用程序消息队列中丢失。

通过写入日志消息的过程(不可能直接调试,因为这会扰乱导致问题所需的时间),我发现后台线程确实正在发布消息(并从 PostThreadMessage 获得积极响应) ,但它们从未出现在我的 TApplication.OnMessage 事件代码中。

我发现各种库中的一些偷偷摸摸的代码会设置自己的 PeekMessage/TranslateMessage/DispatchMessage 循环,但并非所有人都记得检查是否有 TApplication.OnMessage 事件。但我刚刚搜索了 VCL 代码和我正在使用的十几个第三方库,并没有发现任何在这种情况下会受到影响的实例(据我所知)。

注意:我正在使用 madExcept、Indy、FastReport、AddictSpell、SynEdit、VclStyleUtils(以及其他一些鲜为人知的库)

注 2:我想知道它是否可能与 Delphi 10.2.1 或 Windows 10 Creator 的更新有关,因为我还看到了一些其他奇怪的行为(第一个异常或第一个 TOpenDialog 出现长时间延迟 - 但仅在某些情况下)应用程序),这在 10.1 中绝对不会发生(我没有使用 10.2.0)。 ...但这可能(可能是)有所不同。

所以我的问题是:我该怎么办?

关于如何查找/验证是否有其他代码窃取应用程序消息有什么建议吗?除了 PeekMessage 之外我还应该搜索什么?

是否有另一种方法来拦截应用程序消息队列消息,可以让我避免该问题?

如果没有更好的选择,我可能不得不放弃使用应用程序线程消息并实现我自己的消息/同步系统,在其余时间让其他系统运行良好后,我宁愿不这样做。

最佳答案

您提到了PostThreadMessage。别再看了。除非您控制所有可能拉出线程消息的消息循环,否则您不能使用它,但您没有控制。模式文件对话框消息循环不受您的控制。它将拉出用于不同消息循环的线程消息,并且不知道如何处理它们。

解决方案很简单。将消息发布到窗口而不是线程。这样,所有正常的消息循环(模式文件对话框的消息循环是正常的)都会将消息分派(dispatch)到预期的接收者窗口。

用 Delphi 术语来说,这将涉及使用 AllocateHWnd 或类似的方法来创建一个隐藏窗口来接收消息。

Raymond Chen 在此讨论了此主题:Why do messages posted by PostThreadMessage disappear?

关于multithreading - 使用 TSaveDialog 了解应用程序线程消息丢失的原因,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45983526/

36 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com