COM+ app not continuing until some unknown condition












0















I have a COM+ application which I instantiate with



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


This is followed by event initialization



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


I have an MFC application with following:



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


also in the Dialog class there is



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


When running, after clicking Btn1 two things happen: 1.OnSomething() is fired, and 2. the COM+ does a bunch of other stuff it should do. So far so good.



The interesting thing is that 1 & 2 happen only after OnBtn1Clicked() is exited. Even if i put a sleep() after DoSomething() or if I attempt to call DoSomething() within a different thread, 1 + 2 don't happen only after OnBtn1Clicked() is cleared.



From The COM component log I see it reaches and enters it's OnSomething() call but does not exist it (and of course does not reach the client side sink) until OnBtn1Clicked() is cleared. Once cleared, the sink is reached and the COM component continues execution.



All this would not be a problem since I can wait for after the button is clicked, but I need to implement this in a console application client. When implementing in a console application I was not able to make 1 and/or 2 happen. Only after I kill the client process (!) 2 happens (the COM+ continues processing) but of course client side OnSomething() does not since the process is dead.



Any idea what happens when OnBtn1Clicked() is cleared that affects the COM+?










share|improve this question




















  • 1





    Sounds like this is running in an STA. All method calls to COM objects in an STA are synchronized with the message queue. This requires that you keep dispatching messages for method calls to be executed, which you aren't while your code is in a message handler (OnBtn1Clicked). See Processes, Threads, and Apartments.

    – IInspectable
    Nov 28 '18 at 16:31













  • (see my edit) How can I release the message queue from within a console application?

    – grunt
    Nov 28 '18 at 16:43











  • There is no difference. You dispatch messages in a console application the same way you dispatch messages in a GUI application.

    – IInspectable
    Nov 28 '18 at 16:56











  • understood, but the message queue is "stuck" until client terminates. dispatching more message will probably not release it. I guess MFC has some method that "releases" the queue or "dispatches" the previous message.

    – grunt
    Nov 28 '18 at 17:04






  • 1





    MFC implements a (regular) message loop. Your console application needs to do the same on its STA COM threads. Difficult to suggest anything more substantial without seeing any code (or even getting an answer as to whether the affected COM object lives in an STA).

    – IInspectable
    Nov 28 '18 at 17:23
















0















I have a COM+ application which I instantiate with



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


This is followed by event initialization



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


I have an MFC application with following:



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


also in the Dialog class there is



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


When running, after clicking Btn1 two things happen: 1.OnSomething() is fired, and 2. the COM+ does a bunch of other stuff it should do. So far so good.



The interesting thing is that 1 & 2 happen only after OnBtn1Clicked() is exited. Even if i put a sleep() after DoSomething() or if I attempt to call DoSomething() within a different thread, 1 + 2 don't happen only after OnBtn1Clicked() is cleared.



From The COM component log I see it reaches and enters it's OnSomething() call but does not exist it (and of course does not reach the client side sink) until OnBtn1Clicked() is cleared. Once cleared, the sink is reached and the COM component continues execution.



All this would not be a problem since I can wait for after the button is clicked, but I need to implement this in a console application client. When implementing in a console application I was not able to make 1 and/or 2 happen. Only after I kill the client process (!) 2 happens (the COM+ continues processing) but of course client side OnSomething() does not since the process is dead.



Any idea what happens when OnBtn1Clicked() is cleared that affects the COM+?










share|improve this question




















  • 1





    Sounds like this is running in an STA. All method calls to COM objects in an STA are synchronized with the message queue. This requires that you keep dispatching messages for method calls to be executed, which you aren't while your code is in a message handler (OnBtn1Clicked). See Processes, Threads, and Apartments.

    – IInspectable
    Nov 28 '18 at 16:31













  • (see my edit) How can I release the message queue from within a console application?

    – grunt
    Nov 28 '18 at 16:43











  • There is no difference. You dispatch messages in a console application the same way you dispatch messages in a GUI application.

    – IInspectable
    Nov 28 '18 at 16:56











  • understood, but the message queue is "stuck" until client terminates. dispatching more message will probably not release it. I guess MFC has some method that "releases" the queue or "dispatches" the previous message.

    – grunt
    Nov 28 '18 at 17:04






  • 1





    MFC implements a (regular) message loop. Your console application needs to do the same on its STA COM threads. Difficult to suggest anything more substantial without seeing any code (or even getting an answer as to whether the affected COM object lives in an STA).

    – IInspectable
    Nov 28 '18 at 17:23














0












0








0








I have a COM+ application which I instantiate with



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


This is followed by event initialization



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


I have an MFC application with following:



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


also in the Dialog class there is



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


When running, after clicking Btn1 two things happen: 1.OnSomething() is fired, and 2. the COM+ does a bunch of other stuff it should do. So far so good.



The interesting thing is that 1 & 2 happen only after OnBtn1Clicked() is exited. Even if i put a sleep() after DoSomething() or if I attempt to call DoSomething() within a different thread, 1 + 2 don't happen only after OnBtn1Clicked() is cleared.



From The COM component log I see it reaches and enters it's OnSomething() call but does not exist it (and of course does not reach the client side sink) until OnBtn1Clicked() is cleared. Once cleared, the sink is reached and the COM component continues execution.



All this would not be a problem since I can wait for after the button is clicked, but I need to implement this in a console application client. When implementing in a console application I was not able to make 1 and/or 2 happen. Only after I kill the client process (!) 2 happens (the COM+ continues processing) but of course client side OnSomething() does not since the process is dead.



Any idea what happens when OnBtn1Clicked() is cleared that affects the COM+?










share|improve this question
















I have a COM+ application which I instantiate with



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


This is followed by event initialization



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


I have an MFC application with following:



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


also in the Dialog class there is



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


When running, after clicking Btn1 two things happen: 1.OnSomething() is fired, and 2. the COM+ does a bunch of other stuff it should do. So far so good.



The interesting thing is that 1 & 2 happen only after OnBtn1Clicked() is exited. Even if i put a sleep() after DoSomething() or if I attempt to call DoSomething() within a different thread, 1 + 2 don't happen only after OnBtn1Clicked() is cleared.



From The COM component log I see it reaches and enters it's OnSomething() call but does not exist it (and of course does not reach the client side sink) until OnBtn1Clicked() is cleared. Once cleared, the sink is reached and the COM component continues execution.



All this would not be a problem since I can wait for after the button is clicked, but I need to implement this in a console application client. When implementing in a console application I was not able to make 1 and/or 2 happen. Only after I kill the client process (!) 2 happens (the COM+ continues processing) but of course client side OnSomething() does not since the process is dead.



Any idea what happens when OnBtn1Clicked() is cleared that affects the COM+?







mfc com+






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 28 '18 at 16:39







grunt

















asked Nov 28 '18 at 16:22









gruntgrunt

3251217




3251217








  • 1





    Sounds like this is running in an STA. All method calls to COM objects in an STA are synchronized with the message queue. This requires that you keep dispatching messages for method calls to be executed, which you aren't while your code is in a message handler (OnBtn1Clicked). See Processes, Threads, and Apartments.

    – IInspectable
    Nov 28 '18 at 16:31













  • (see my edit) How can I release the message queue from within a console application?

    – grunt
    Nov 28 '18 at 16:43











  • There is no difference. You dispatch messages in a console application the same way you dispatch messages in a GUI application.

    – IInspectable
    Nov 28 '18 at 16:56











  • understood, but the message queue is "stuck" until client terminates. dispatching more message will probably not release it. I guess MFC has some method that "releases" the queue or "dispatches" the previous message.

    – grunt
    Nov 28 '18 at 17:04






  • 1





    MFC implements a (regular) message loop. Your console application needs to do the same on its STA COM threads. Difficult to suggest anything more substantial without seeing any code (or even getting an answer as to whether the affected COM object lives in an STA).

    – IInspectable
    Nov 28 '18 at 17:23














  • 1





    Sounds like this is running in an STA. All method calls to COM objects in an STA are synchronized with the message queue. This requires that you keep dispatching messages for method calls to be executed, which you aren't while your code is in a message handler (OnBtn1Clicked). See Processes, Threads, and Apartments.

    – IInspectable
    Nov 28 '18 at 16:31













  • (see my edit) How can I release the message queue from within a console application?

    – grunt
    Nov 28 '18 at 16:43











  • There is no difference. You dispatch messages in a console application the same way you dispatch messages in a GUI application.

    – IInspectable
    Nov 28 '18 at 16:56











  • understood, but the message queue is "stuck" until client terminates. dispatching more message will probably not release it. I guess MFC has some method that "releases" the queue or "dispatches" the previous message.

    – grunt
    Nov 28 '18 at 17:04






  • 1





    MFC implements a (regular) message loop. Your console application needs to do the same on its STA COM threads. Difficult to suggest anything more substantial without seeing any code (or even getting an answer as to whether the affected COM object lives in an STA).

    – IInspectable
    Nov 28 '18 at 17:23








1




1





Sounds like this is running in an STA. All method calls to COM objects in an STA are synchronized with the message queue. This requires that you keep dispatching messages for method calls to be executed, which you aren't while your code is in a message handler (OnBtn1Clicked). See Processes, Threads, and Apartments.

– IInspectable
Nov 28 '18 at 16:31







Sounds like this is running in an STA. All method calls to COM objects in an STA are synchronized with the message queue. This requires that you keep dispatching messages for method calls to be executed, which you aren't while your code is in a message handler (OnBtn1Clicked). See Processes, Threads, and Apartments.

– IInspectable
Nov 28 '18 at 16:31















(see my edit) How can I release the message queue from within a console application?

– grunt
Nov 28 '18 at 16:43





(see my edit) How can I release the message queue from within a console application?

– grunt
Nov 28 '18 at 16:43













There is no difference. You dispatch messages in a console application the same way you dispatch messages in a GUI application.

– IInspectable
Nov 28 '18 at 16:56





There is no difference. You dispatch messages in a console application the same way you dispatch messages in a GUI application.

– IInspectable
Nov 28 '18 at 16:56













understood, but the message queue is "stuck" until client terminates. dispatching more message will probably not release it. I guess MFC has some method that "releases" the queue or "dispatches" the previous message.

– grunt
Nov 28 '18 at 17:04





understood, but the message queue is "stuck" until client terminates. dispatching more message will probably not release it. I guess MFC has some method that "releases" the queue or "dispatches" the previous message.

– grunt
Nov 28 '18 at 17:04




1




1





MFC implements a (regular) message loop. Your console application needs to do the same on its STA COM threads. Difficult to suggest anything more substantial without seeing any code (or even getting an answer as to whether the affected COM object lives in an STA).

– IInspectable
Nov 28 '18 at 17:23





MFC implements a (regular) message loop. Your console application needs to do the same on its STA COM threads. Difficult to suggest anything more substantial without seeing any code (or even getting an answer as to whether the affected COM object lives in an STA).

– IInspectable
Nov 28 '18 at 17:23












1 Answer
1






active

oldest

votes


















0














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);
}





share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53523910%2fcom-app-not-continuing-until-some-unknown-condition%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    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);
    }





    share|improve this answer




























      0














      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);
      }





      share|improve this answer


























        0












        0








        0







        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);
        }





        share|improve this answer













        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);
        }






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Dec 3 '18 at 16:48









        gruntgrunt

        3251217




        3251217
































            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53523910%2fcom-app-not-continuing-until-some-unknown-condition%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            A CLEAN and SIMPLE way to add appendices to Table of Contents and bookmarks

            Calculate evaluation metrics using cross_val_predict sklearn

            Insert data from modal to MySQL (multiple modal on website)