我正在研究一个小应用程序,它意味着调用一些(非常多样化的)函数,这些函数很遗憾地不受我的控制,并且设计的方式使我在完成正确的用户操作时不知道。特别是其中一些产生了一个线程来完成他们的工作,最终在将来某个时候死亡。所以有些是同步实现的,有些是异步实现的,而我的代码不知道它将是哪一个。
我的应用程序的唯一目的是启动这些任务并在完成后终止。由于目的是自动化,我预计它会在几分钟内从批处理文件中被调用100次,所以我不希望这个过程比绝对可能的更长久。
由于我没有信号可以等待,我的主线程上的ExitThread()
似乎是要走的路,所以外部代码生成的任何线程都会在终止时终止进程。 / p>
现在就谈谈我在标题中提到的实际问题。 :)为了获得我的夹具的正确接口,我需要搞乱一些COM功能。 SHParseDisplayName
,IShellFolder::GetUIObjectOf
和其他一些人。但是在我完成这些接口并释放它们之后很久,这些线程仍然存在。甚至在我打电话给CoUninitialize()
。
使用Process Explorer检查我的进程时,大多数这些线程似乎都有ntdll.dll@EtwTraceMessageVa
作为入口点,并且卡在ntdll.dll!ZwAlpcSendWaitReceivePort+0xa
中。显然,使用TerminateThread
随机终止线程不是一个选项。
当我完成使用它时,如何让COM终止这些线程?我正在使用W7 x64进行开发。
答案 0 :(得分:4)
这些线程不属于COM。它们属于本机Windows线程池。它们设计用于粘贴,以便在必要时可以重复使用。假设没有挂起的异步回调,您应该能够干净地关闭。线程池将负责及时销毁线程。
答案 1 :(得分:0)
我弄清楚了问题,这是一个显而易见的案例,所有文档都在某个地方,但不在你看的地方,而且一个有点相关的主题在这个问题上有一个blog post,这让我找不到片。
我的应用会弹出IContextMenu
个文件(因此我的代码中没有ShellExecute
),然后允许用户调用命令。但是,像properties
这样的一些动词是我的问题所涉及的奇怪之处:它们产生了另一个线程并且没有给出通知或明显阻止它的方法。
使用链接帖子中提到的SHSetExplorerInstance修复了我的问题。 :)