如何:获取从后台线程 (C++) 中的服务

服务无法通过从后台线程的 IServiceProvider.QueryService 获取。 如果使用 QueryService 获取在主线程中的服务,然后尝试使用在后台线程上的服务,它还会失败。

获取从后台线程中的服务,在 IVsPackage.SetSite 方法使用 CoMarshalInterThreadInterfaceInStream 封送处理服务提供程序到主线程的流。 然后可以 unmarshal 在后台线程上的服务提供程序以及使用它访问服务。 您一次只能 unmarshal,因此缓存该接口则会返回。

备注

托管代码自动让线程之间的接口,因此,获取服务从后台线程不需要特殊的代码。

示例

下面的代码将在主线程中向服务提供程序并提供 QueryServiceFromBackgroundThread 方法。 unmarshal 服务提供程序获取从后台线程中的服务。

class CMyPackage : public IVsPackage
{
private:
    // Used to marshal IServiceProvider between threads
    CComPtr< IStream > m_pSPStream;
    // IServiceProvider proxy for the background thread
    CComPtr< IServiceProvider > m_pBackgroundSP;

public:
    HRESULT SetSite( IServiceProvider* pSP )
    {
        // Marshal the service provider into a stream so that
        // the background thread can retrieve it later
        CoMarshalInterThreadInterfaceInStream(
            IID_IServiceProvider, pSP, &m_pSPStream);

        //... do the rest of your initialization
    }

    // Call this when your background thread needs to call QueryService
    // The first time through, it unmarshals the interface stored 
    HRESULT QueryServiceFromBackgroundThread(
        REFGUID rsid,        // [in] Service ID
        REFIID riid,         // [in] Interface ID
        // [out] Interface pointer of requested service (NULL on error)
        void **ppvObj
    {
        if( !m_pBackgroundSP )
        {
            if( !m_pSPStream )
            {
                return E_UNEXPECTED;
            }

            HRESULT hr = CoGetInterfaceAndReleaseStream( 
                m_pSPStream, IID_IServiceProvider, 
                (void **)&m_pBackgroundSP );
            if( FAILED(hr) )
            {
                return hr;
            }

            // The CoGetInterfaceAndReleaseStream has already 
            // destroyed the stream.  To avoid double-freeing, 
            // the smart wrapper needs to be detached.
            m_pSPStream.Detach();
        }

        return m_pBackgroundSP->QueryService( rsid, riid, ppvObj );
    }
};

请参见

概念

服务 Essentials

其他资源

服务