A组件实现IA接口,使用套间线程模式。
IA接口有一函数IAFunc。A组件实现IAFunc函数时,内部为一死循环,等待超时退出或等待取消信号(一成员变量)退出。
在循环内部添加了消息处理部分:
MSG msg;
while(PeekMessage(&msg,NULL,0,0,PM_REMOVE){
DispatchMessage(&msg);}
程序TEST(MFC Dialog)中通过#import导入了A组件,TEST的主线程通过CoInitialize(NULL)进行COM初始化。在主线程中通过智能指针.CreateInstance创建了一个对象,调用正常。问题出现在下面:
通过CoMarshalInterThreadInterfaceInStream和CoGetInterfaceAndReleaseStream函数将在主线程中创建的对象传递到工作线程(非UI线程,无消息循环)时,在工作线程中调用该对象的IAFunc函数时,会导致主线程UI无响应。
如果不使用列集,而直接传递智能指针到线程函数的参数,在线程中将该参数再直接用reinterpret_cast转换为A对象的智能指针,在工作线程中调用该对象的IAFunc函数时,不会导致主线程UI无响应。
工作线程中通过CoInitialize(NULL)初始化(也尝试过使用CoInitializeEx(NULL,COINIT_APARTMENTTHREADED),结果一样)。原因为何?应该如何解决?

解决方案 »

  1.   

    使用同时wait消息和事件试试,不要做成死循环.
    不知道具体卡死在哪个地方....
      

  2.   

    问题反问:主线程调用CoMarshalInterThreadInterfaceInStream之后在干什么?有没有处于消息循环中?请确保处于消息循环中。
    组件设计也是有问题的,不要在接口方法里面执行死循环或者等待操作,应该马上返回,否则容易陷入死锁。如果你要在组件中等待某个信号,尝试启动一个线程来等待,收到信号后再通过连接点的方式通知调用者。
      

  3.   

    CoMarshalInterThreadInterfaceInStream是在Dialog的OnInitDialog函数中调用的,调用CoMarshalInterThreadInterfaceInStream后的下一个动作就是CreateThread,然后就返回TRUE了。现在的问题是组件的IAFunc是运行在工作线程中,而阻塞的是主线程的UI,未死锁。
      

  4.   

    谢谢您的回复。伪代码如下:
    组件(APARTMENT):HRESULT IAFunc(...){while(true){if(超时)return S_FALSE;//超时时间一般设为数十秒......//此处做实际工作MSG msg;while(PeekMessage(&msg,NULL,0,0,PM_REMOVE)){TranslateMessage(&msg);DispatchMessage(&msg);}}}测试工程是MFC based on dialog工程,通过import导入组件生成的dll,在工程中使用IDE生成的智能指针.主对话框的OnInitDialog函数伪代码如下:BOOL CXDialog::OnInitDialog(){CoInitialize(NULL);组件.CreateInstance;IStream *pStream;CoMarshanInterThreadInterfaceInStream(...,&pStream);CreateThread(threadFunc,pStream);return TRUE;}threadFunc伪代码如下:UINT threadFunc(LPVOID param){CoInitialize(NULL);IMyInterface *pInterface;CoGetInterfaceAndReleaseStream(IID_IMyInterface,&pInterface,(IStream *)param);pInterface->IAFunc();pInterface->Release();CoUninitialize();return 0;}以上代码中省略了错误检查,测试过程中也未发生其它错误.代码执行的现象是堵塞了主线程(主对话框)的UI.
      

  5.   

    问题稀里糊涂的解决了,也不知道怎么回事.
    看了您的ATL实现的CDHtmlDialog模板类v1.03,很是景仰,给分.