0

编辑:根据以下评论中的信息更新问题


客户端:32 位 COM 客户端

服务器:配置为在进程外运行的 64 位 COM 进程内服务器。服务器调用本机 C++ 代码

我试图在 dllhost 的帮助下运行一个进程外的 COM 对象。32 位测试客户端在每个单独的测试用例中运行良好。但是,当我尝试使用批处理文件连续运行这些案例时,它会因 InteropServices.COMException: RPC failed (HRESULT 0x800706BE) 而崩溃。每个测试用例都是一个程序,结构如下

var ComType = Type.GetTypeFromProgID("My.COMClass");
var ComObject = Activator.CreateInstance(ComType);
ComType.InvokeMember("SomeFunction", BindingFlags.InvokeMethod, null, ComObject, null);
Marshal.ReleaseComObject(ComObject);

当我使用以下方式运行测试时发生崩溃

//test1.bat
TestA.exe
TestB.exe //crash
//test2.bat
TestB.exe
TestA.exe //crash

当我单独运行每个测试时没有问题。我还注意到,如果在调用下一个测试之前等待 dllhost 进程完全完成(并消失),整个批处理文件将毫无问题地运行。

//test3.bat
TestA.exe
pause //wait a few seconds then press enter
TestB.exe //ok

由于每个测试都完美地单独运行,我认为代码很好,这只是我如何执行测试的问题,但是我找不到关于这个问题的任何信息,所以我很感激对此的任何见解

64 位 COM 服务器实际上只是一个 C++ dll 的 COM 包装器,我们在基础上编写了包装器。还值得一提的是,在尝试 COM 包装器之前,我的原始 C++ dll 工作正常

4

1 回答 1

-1

我找到了我的问题的原因。这是因为我原来的 C++ dll 正在创建线程来自己处理并发,根据Inside COM+: Base Services,COM 对象代码不应该这样做

由于系统会根据需要自动生成线程以启用对组件的并发访问,因此您应该避免调用 Win32 CreateThread 函数。事实上,强烈建议不要在组件中调用 CreateThread 来启用并发,因为在大多数情况下这会干扰系统的线程池算法

我仍然不完全确定线程处理如何导致这个问题,所以如果有人可以分享更详细的解释,那就太好了,但现在,只要我删除 C++ dll 中的多线程代码就可以了。

于 2021-08-03T03:31:24.523 回答