我什么时候应该打电话给CoUninitialize?

时间:2012-12-13 15:29:23

标签: c com mta

我在DLL中实现了一个函数,封装了对Out-OF-Proc COM服务器的异步调用。它看起来像这样:

    HRESULT hr = S_OK;
    bool bCoInitialized = false;
    IXXXXInterface* pServer = NULL;
    ISynchronize* pISynchronize = NULL;
    AsyncIXXXXInterface* pAsyncServer = NULL;
    ICancelMethodCalls* pICancel = NULL;

    hr = CoInitializeEx(NULL,COINIT_MULTITHREADED);
    if (hr == S_OK || hr == S_FALSE) {
        bCoInitialized = true;
    }
    else if(hr == RPC_E_CHANGED_MODE) {
        bCoInitialized = false;
    }
    else{
        bCoInitialized = false;
        goto cleanup
    }
    hr = CoCreateInstance(CLSID_XXXXInterface, NULL,
        CLSCTX_ALL|CLSCTX_ACTIVATE_64_BIT_SERVER, IID_IXXXXInterface, (void**)&pServer);
    if (FAILED (hr)) {
        goto cleanup
    }

    ICallFactory* pCallFactory;
    hr = pServer->QueryInterface (IID_ICallFactory, (void**) &pCallFactory);
    if (FAILED (hr)) {
        goto cleanup
    }

    hr = pCallFactory->CreateCall (IID_AsyncIXXXXInterface, NULL, IID_AsyncIXXXXInterface,
        (IUnknown**) &pAsyncServer);
    pCallFactory->Release();
    if (FAILED (hr)) {
        goto cleanup
    }

    hr = pAsyncServer->QueryInterface(IID_ISynchronize,  (void**) &pISynchronize);
    if (FAILED (hr)) {
        goto cleanup
    }

    hr = pAsyncServer->QueryInterface(IID_ICancelMethodCalls, (void**) &pICancel);
    if (FAILED (hr)) {
        goto cleanup
    }

    // Do something use the async interface.
cleanup:    
    if(pICancel)
        pICancel->Release();
    if(pISynchronize)
        pISynchronize->Release();
    if(pAsyncServer)
        pAsyncServer->Release();
    if(pServer)
        pServer->Release();
    if(bCoInitialized)     // If I comment out these 
        CoUninitialize();  // 2 lines, it will be OK.

问题是当我在多线程中调用该函数时,有时它会在COM的工作线程中使用调用堆栈在combase.dll中抛出异常。 如果我只注释掉最后两行,那就没问题了。看起来CoUnitialize()将释放所有资源,而COM线程池中的工作线程在某些情况下仍然使用它们。我不确定我的情况是否正确,或者其他地方是否有问题。如果我是对的,如何通过使用哪个API等待工作线程释放所有资源来避免此问题?

0 个答案:

没有答案