Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Создание события из дополнительного потока

1.8K
21 ноября 2009 года
Arkady
153 / / 18.12.2007
Доброго времени суток,

Есть COM+ сервер, внутри которого крутится дополнительный поток, который должен уметь генерировать события.
MSDN для этого предлагает маршализовать интерфейс событий в доп. поток, тогда вызов методов этого интерфейса событий из доп. потока должен выполняться корректно.
Я для этого использую GlobalInterfaceTable (GIT).

Следующим образом:
Код:
//Переопределяю методы интерфейса 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();
}


Метод действительно успешно попадает в GIT, и во время выполнения FireEvent действительно достается из GIT. И Event->OnListenStart(); отрабатывается.
Однако если Fire_OnListenStart(void) находится в доп. потоке, то вызов Event->OnListenStart(); не влечет за собою самого события, написанного клиентом и переданного через этот интерфейс.
Если же Fire_OnListenStart(void) находится в основном потоке, то событие, написанное клиентом и переданное через этот интерфейс - отрабатывается.

Кто-нибудь может мне помочь и подсказать - почему? Казалось бы, теоретически всё правильно сделано...
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог