//Переопределяю методы интерфейса IConnectionPoints, advise и
//unadvise, чтобы заносить и выносить входящий от клиента интерфейс в
//GIT,
template <class T>
STDMETHODIMP TEvents_UpTask<T>::Advise(IUnknown* pUnkSink,
DWORD* pdwCookie)
{
T* pT = static_cast<T*>(this);
IUnknown* p;
IID iid;
GetConnectionInterface(&iid);
HRESULT hRes = pUnkSink->QueryInterface(iid, (void**)&p);
if (SUCCEEDED(hRes))
{
pT->Lock();
DWORD myCookie;
gp_GIT->RegisterInterfaceInGlobal(p, IID_IDispatch, &myCookie);
//это std::map<DWORD, DWORD> для хранения всех Cookie
m_GitPointers[*pdwCookie] = myCookie;
pT->Unlock();
}
return hRes;
}
template <class T>
STDMETHODIMP TEvents_UpTask<T>::Unadvise(DWORD dwCookie)
{
...
//Arkady Add
gp_GIT->RevokeInterfaceFromGlobal(m_GitPointers[dwCookie]);
...
}
//метод, который должен вызываться при старте потока, генерирующего данные (такого же, как у Вас).
template <class T> HRESULT
TEvents_UpTask<T>::Fire_OnListenStart(void)
{
DWORD dw;
T * pT = (T*)this;
pT->Lock();
IUnknown ** pp = m_vec.begin();
while (pp < m_vec.end())
{
if (*pp != NULL)
{
dw = (DWORD)pp;
IDispatch* dp;
HRESULT hr = gp_GIT->GetInterfaceFromGlobal(m_GitPointers[dw], IID_IDispatch, (void**)&dp);
if (SUCCEEDED(hr))
{
IUpTaskEvents* Event;
hr = dp->QueryInterface(DIID_IUpTaskEvents, (void**)&Event);
if (SUCCEEDED(hr))
{
Event->OnListenStart();
}
}
}
pp++;
}
pT->Unlock();
}
Создание события из дополнительного потока
Есть COM+ сервер, внутри которого крутится дополнительный поток, который должен уметь генерировать события.
MSDN для этого предлагает маршализовать интерфейс событий в доп. поток, тогда вызов методов этого интерфейса событий из доп. потока должен выполняться корректно.
Я для этого использую GlobalInterfaceTable (GIT).
Следующим образом:
Код:
Метод действительно успешно попадает в GIT, и во время выполнения FireEvent действительно достается из GIT. И Event->OnListenStart(); отрабатывается.
Однако если Fire_OnListenStart(void) находится в доп. потоке, то вызов Event->OnListenStart(); не влечет за собою самого события, написанного клиентом и переданного через этот интерфейс.
Если же Fire_OnListenStart(void) находится в основном потоке, то событие, написанное клиентом и переданное через этот интерфейс - отрабатывается.
Кто-нибудь может мне помочь и подсказать - почему? Казалось бы, теоретически всё правильно сделано...