【问题标题】:Message loop issue using SetParent to embed window into external process使用 SetParent 将窗口嵌入外部进程的消息循环问题
【发布时间】:2014-03-02 18:20:01
【问题描述】:

我的 Windows 应用程序有一个选项卡式界面。每个选项卡都会呈现一些 UI 内容。众所周知,如果我在主线程中执行一个非常耗时的 for 循环,而不让其他人处理任何 Windows 消息,应用程序将被冻结。在冻结期间,我无法切换标签。

Google Chrome 的多进程架构启发了我。我尝试使用SetParentembed a process into another process。更具体地说:进程 A 是主进程。它可以创建无限的工作进程。每个工作进程都有自己的消息循环。如果进程 B 被冻结,则进程 A 和任何其他工作进程不应被冻结。

其实我错了:如果我点击一个按钮工作进程B在主线程中不停地做很多UI的事情,不仅进程B的UI而且进程A的UI都会被阻塞,直到我的测试代码结束。

有人可以分享一些灯给我吗?

【问题讨论】:

标签: multithreading delphi user-interface blocking sendmessage


【解决方案1】:

你正在尝试做的是,呃,很难做到正确。建议大家先阅读Raymond Chen的文章:Is it legal to call have a cross-process parent/child or owner/owned window relationship

创建跨线程父/子或所有者/拥有窗口关系隐式附加这些窗口所属线程的输入队列,并且此附加是可传递的:如果这些队列之一附加到第三个队列,则所有三个队列都相互连接。更一般地,由父/子或所有者/拥有或共享线程关系链相关的所有窗口的队列相互附加。

这正是您描述的场景。并且所有消息队列的融合是意料之中的。您拥有多个进程的事实并不会改变您不能阻塞 UI 线程的事实。

所以我认为你的程序设计有缺陷。你增加了史诗般的复杂性,却没有任何回报。多进程架构的好处是安全和隔离。关于阻塞 UI 线程,您无需更改任何内容。解决问题的唯一方法是将长时间运行的任务放在非 UI 线程上。我强烈的建议是回到单一的流程设计。

【讨论】:

  • 单一流程设计并不能解决我的问题。我想在标签中呈现不同的 UI 内容。实际上我确实有长时间运行的 UI 任务。如果我使用单个进程并且一个选项卡冻结,则整个 UI 都会冻结。
  • 单进程就可以解决。将长时间运行的任务放入工作线程。你只是做得不对。我不能说比这更清楚了:不要阻塞 UI 线程。
  • 例如,我在应用程序中嵌入了一个 TWebBrowser。浏览器加载一个 html,它将运行一个长时间运行的 javascript。在 javascript 结束之前,UI 将被冻结。我无法控制浏览器控件的 javascript 在线程中运行。
  • 在 Chrome 中它们不会阻塞 UI 线程。你问的问题是为什么阻塞一个 UI 线程会阻塞所有线程。正如 Raymond 的文章中所解释的,答案是您的所有 UI 线程都已附加。
  • 仅供参考,最新版本的 IE 也为其选项卡使用多进程方法。它不仅隔离 UI,还隔离内存和资源。如果给定进程被恶意代码破坏,则只有一个选项卡被破坏,而不是整个浏览器。
猜你喜欢
  • 1970-01-01
  • 2010-09-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多