【问题标题】:Why is trying to open a TOpenDialog spawning a ton of threads?为什么要尝试打开生成大量线程的 TOpenDialog?
【发布时间】:2011-09-10 17:10:45
【问题描述】:

我有一个非常简单的表单,上面有一个 TOpenDialog 和一个按钮。当我按下按钮时,它会在对话框中调用 Execute。如果我在调试器中观察,打开对话框的行为会产生 14 个线程,当我关闭对话框时它们也不会消失。

有人知道这是怎么回事吗?

【问题讨论】:

  • 只有 14 个?感觉就像整个操作系统都在启动……就我个人而言,我一直不明白为什么要花这么长时间才能显示一个文件对话框。
  • 还有 +1,因为你让我学到了新东西。这种显着的延迟在您通过调试器运行应用程序时出现。
  • 我记得读过通用文件对话框最终会加载所有 shell 扩展名,因此那些 DLL 可能会在做什么,天知道。
  • @Luke:好的,这是有道理的。你还记得读过任何事后卸载它们的方法吗?
  • @Mason:我猜你根本不需要关心它们。毕竟,Microsoft 和 Embarcadero 都不傻……而且,正如我刚刚了解到的,可怕的延迟只会在您通过调试器运行程序时出现。您有什么特别的理由说明这对您来说是个问题吗?

标签: windows multithreading delphi topendialog


【解决方案1】:

想象一下,您想向您的朋友展示太平洋西北地区的美丽。你决定出发去拍几张sunset over the Pacific 的照片。您真正关心的是回家的图像文件,然后可以将它们上传到 Facebook。实际上,需要将相机、镜头和三脚架拖过Olympics 并返回。您还需要带上负责设置相机并按下快门的摄影师(您自己)。摄影师需要在相对舒适的情况下移动到那里和回来,因此您可以坐在摄影师在旅行时休息的座位上。这个座位被封闭在一个闪亮的金属盒子里,里面有一堆其他的金属、玻璃和橡胶部件,其中一些正在转动和往复运动。最后,大约两吨的东西(和一个活人)进行了数小时的旅行,燃烧了加仑的碳氢化合物液体——目的是将一些信息从岸上转移到互联网上。

完全相同的事情发生在您的应用程序中。当用户想要使用“打开文件”对话框打开文件时,用户希望能够:

  • 导航到包含文件的目录(该目录可能在本地硬盘驱动器或CD/DVD/BR或网络驱动器或存档等。媒体可能已加密或压缩,需要以不同方式显示。媒体可能未插入,可能需要提示用户。媒体可能需要用户的凭据,必须询问);
  • 使用其 URI/UNC 连接到新目录(映射驱动器);
  • 在目录中搜索一些关键字;
  • 复制/删除/重命名一些文件;
  • 查看该目录中的文件列表;
  • 预览目录中每个文件的内容;
  • 选择要打开的文件;
  • 改变主意,决定不打开文件;
  • 做许多其他与文件相关的事情。

操作系统通过本质上为您的进程提供大部分 Windows 资源管理器功能来实现这一切。其中一些必须在后台发生,否则用户会抱怨“打开文件”对话框反应迟钝。在后台运行某些任务的明显方法是在不同的线程上运行它们。这就是我们所看到的。

你问留下的线怎么办?好吧,其中一些留在那里,以供用户决定打开另一个文件的情况:在这种情况下,它节省了大量时间、流量和打字。上次用于这一特定过程的自定义身份验证? ——存储。那些讨厌的 PDF 的预览图标? - 还在那儿。目录中每部电影的长度和比特率? -- 仍然可用,无需重新解析。

当然,这些线程不仅仅是神奇地自行出现。检查有多少 DLL 已映射到进程中。查看其中的一些,您可以非常有趣地了解添加了哪些功能。

查看它的另一种有趣方式是在创建每个线程时转储调用堆栈。这显示了哪个 DLL(有时是哪个对象)创建了它们。 Here's x64 Win7 如何创建所有线程。可以发现 Explorer 框架的线程正在创建中;一些用于实例化文件过滤器的 OLE 活动,其中一些可以生成预览图标、覆盖和工具提示;属于搜索子系统的线程很少; shell 的设备枚举器(因此如果用户插入新设备,它将自动出现在打开的对话框中); shell 网络监视器(同上)和其他东西。

好消息是它发生得很快,不会给您的流程增加太多开销。大多数线程大部分时间都在等待一些很少发生的事件(例如插入 USB 密钥),因此 CPU 不会花任何时间执行它们。每个线程在您的进程中消耗 1MB 的 虚拟 地址空间,但实际物理内存只有几个 4Kb 页。而且大多数(如果不是全部)这些 DLL 不使用任何磁盘带宽来加载:它们已经在 RAM 中,因此它们几乎免费被映射到您的进程中。

最终,用户在简洁的 UI 中获得了大量有用的功能,而该过程只需做很少的事情即可实现所有这些。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-13
    • 2016-09-06
    • 1970-01-01
    • 2016-08-27
    • 1970-01-01
    • 2012-07-31
    相关资源
    最近更新 更多