Приложение COM + не работает до неизвестного состояния - PullRequest
0 голосов
/ 28 ноября 2018

У меня есть приложение COM +, которое я создаю с помощью

CoCreateInstance(CLSID_TheComponent, NULL, CLSCTX_ALL, IID_ITheComponent, &m_TheComponent);

Это сопровождается инициализацией события

CoCreateInstance(CLSID_TransientSubscription,NULL,CLSCTX_ALL,IID_ITransinetSubscription,&Trans);
...some more code that eventually registers some CLSID_Events, IID__IEvents.

У меня есть приложение MFC со следующим:

OnBtn1Clicked()
{
  m_TheComponent->DoSomething();
}

также в классе Dialog есть

class CMFCMyDialog : public CDialogEx, _IEvents
{
  ...
  virtual HRESULT STDMETHODCALLTYPE OnSomething(); // abstract in _IEvents

При запуске после нажатия Btn1 происходит две вещи: 1. OnSomething() срабатывает, и 2. COM + делает кучу других вещей, которые он долженделать.Пока все хорошо.

Интересно то, что 1 и 2 происходят только после выхода OnBtn1Clicked().Даже если я поставлю sleep() после DoSomething() или если я попытаюсь вызвать DoSomething() в другом потоке, 1 + 2 не произойдет только после очистки OnBtn1Clicked().

С COMЖурнал компонента, который я вижу, достигает и входит в OnSomething() вызов, но не существует (и, конечно, не достигает приемника на стороне клиента), пока OnBtn1Clicked() не будет очищен.После очистки приемник достигается и COM-компонент продолжает выполнение.

Все это не будет проблемой, поскольку я могу ждать после нажатия кнопки, но мне нужно реализовать это в клиенте консольного приложения.При реализации в консольном приложении я не смог заставить 1 и / или 2 произойти.Только после того, как я уничтожаю клиентский процесс (! ) 2 происходит (COM + продолжает обработку), но, конечно, на стороне клиента OnSomething() нет, поскольку процесс мертв.

Любая идея, что происходиткогда OnBtn1Clicked() очищается, что влияет на COM +?

1 Ответ

0 голосов
/ 03 декабря 2018
MyConsoleClass::MyConsoleClass()
{
    new thread(&MyConsoleClass::Run, this);
}

void MyConsoleClass::Run()
{
    m_ThreadId = GetCurrentThreadId();
    m_IsActive = true;
    MSG msg;
    BOOL bRet;
    while (m_IsActive)
    {
        if (bRet = GetMessage(&msg, NULL, 0, 0) != 0)
        {
            if (bRet == -1)
                // error
            else if (msg.message == WM_QUIT)
                m_IsActive = false;
            else if (msg.message == DO_SOMETHING)
                DoSomething(msg.wParam);
            else
            {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
        }
    }
}

void MyConsoleClass::Invoke(const actionEnum action, const void *params)
{
    PostThreadMessage(m_ThreadId, action, (WPARAM)params, NULL);
}
...