【发布时间】:2012-09-11 07:45:46
【问题描述】:
我正在开发一个 UI 应用程序,它会一路创建一个 COM 对象。 问题是,我想将这个 COM 对象完全“移动”到不同的线程上。
我的做法是这样的:
- 创建我想将对象移动到的新线程(使用 CreateThread API)
- 进入该线程后,我正在调用 PeekMessage 为其设置消息队列
- 调用CoInitialize,CoCreateInstance创建COM对象,QueryInterface得到我想要的接口
- 最后,我在界面上调用了一个方法,该方法显示一个带有 GetCurrentThreadId() 返回值的 MessageBox(我可以访问该对象所在的 COM 库的 VB6 代码)。
问题是,正如此消息框所示,对象方法仍然在原始 UI 线程上执行,而不是在我创建并完成所有这些步骤的线程上执行。还有一点要提一下,在调用接口方法之后,我也在里面设置了一个经典的消息循环。
如何改变这种行为并实现我想要的? (也就是说,我希望源自我新创建的线程的 COM 对象调用在 IT 上执行,而不是在原始应用程序线程上)
这里有一些伪代码使它更清晰:
void myMainUIMethod(){
MessageBox(GetCurrentThreadId()); // displays 1
CreateThread(&myCOMObjectThreadProc);
}
void myCOMObjectThreadProc(){
MessageBox(GetCurrentThreadId()); // displays 2
CoInitialize(NULL);
myObject = CoCreateInstance(myObjectsCLSID);
myObjectInterface = myObject->QueryInterface(myObjectInterfaceCLSID);
myObjectInterface->showThreadIDMessageBox(); // this would be the COM object method call
}
And, in the VB6 code of the object, here's the pseudo-definition of showThreadIDMessageBox.
Public Sub showThreadIDMessageBox()
Call MessageBox(GetCurrentThreadId()) //displays 1, I want it to display 2
End Sub
在创建新线程之前,我通过在主线程上进行 CoUninitalizing 实现了我想要的。但是为什么会这样呢?如果在我创建新线程之前在主线程上初始化了 COM,也许由于某种原因它必须是......我不希望应用程序稍后崩溃,因为我必须在创建新线程之前调用 CoUninitialize。下面是一些伪代码,说明无论哪个线程首先调用 CoInitialize 都会被 STA 对象选中。
void myMainUIMethod(){
MessageBox(GetCurrentThreadId()); // displays 1
CoUninitialize(); // uninitialize COM on the main thread
CreateThread(&myCOMObjectThreadProc);
***i: MessageBox("When you want to initialize COM on main thread, confirm this");
CoInitialize();
}
void myCOMObjectThreadProc(){
MessageBox(GetCurrentThreadId()); // displays 2
***ii: MessageBox("When you want to initialize COM on the new thread, confirm this");
CoInitialize(NULL);
myObject = CoCreateInstance(myObjectsCLSID);
myObjectInterface = myObject->QueryInterface(myObjectInterfaceCLSID);
myObjectInterface->showThreadIDMessageBox(); // this shows 2 IF ***ii is confirmed before ***i, 1 otherwise
}
非常感谢您, 科尼留
【问题讨论】:
标签: multithreading com methods invoke