【发布时间】:2017-06-27 23:05:03
【问题描述】:
在线程中完成任何工作之前,每个线程初始化一次 COM,然后使用尽可能多的 COM 调用,是否正确的 COM 编码?
例如,在我的工作线程中,我设置了 Volume Shadow Copy Service 并使用 IFileOperation,在我的 GUI 线程中,我使用 CoCreateInstance(CLSID_ShellLink...) 在桌面上创建了快捷方式,并且使用CoCreateInstance( CLSID_TaskScheduler...) 创建任务计划程序作业。然后对于所有这些操作,我只需在启动程序和线程时每个线程调用一次HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);。最后当然是 CoUninitialize。
【问题讨论】:
-
不是。你做了一个承诺,穿过你的心,希望死去。提供 COM 运行时无法自行判断的细节。你保证你会发送一个消息循环并且永远不会阻塞线程。你违背了这两个承诺。也许你会逃脱它,取决于。当您的程序死锁或未引发事件时,您知道您没有这样做。你永远不能 100% 确定它是安全的,你不知道在另一台依赖你信守承诺的机器上注入了哪些其他代码。无法调试,不仅仅是因为您不会靠近机器。
-
你能用更简单的术语吗?我有点迷茫.. 作为一个 COM 初学者......你是指使用 COINIT_APARTMENTTHREADED 来处理消息循环吗?做事的最佳方式是什么?
-
是的。获得消息循环并不难,您总是可以从 WPF 或 Winforms 项目模板中获得一个。如果您不想创建窗口,则不必创建。
-
我应该改用 COINIT_MULTITHREADED 吗?我所有的 COM 库调用都在 gui 线程或工作线程中执行,但没有一个对象/调用在线程之间共享 - 我只是使用前面提到的对 VSS/IFileOperation/Task Scheduler/Shell Shortcuts 的调用。跨度>