CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 21
  1. #1
    Join Date
    Jun 2011
    Location
    Antony (near Paris), France
    Posts
    11

    Question Problem: Creation of a modless CDialog in a thread.

    Hello,

    I’m developing an application composed of three threads:
    - The “main” thread, with the user interface and other stuff.
    - A “working” thread that handles messages to perform actions.
    - A “monitoring” thread that is used to load / unload monitoring panels.

    The “main” thread starts both “working” and “monitoring” threads.

    The user can ask to open/close monitoring panels, so the “main” thread posts messages to the “monitoring” thread. When a panel is opened or closed, it registers/unregisters itself to the “working” thread for notifications about the performed actions.

    When the application is closed, the “main” thread stops the “monitoring” and the “working” threads by posting messages.

    In normal processing, every thing works fine.


    My problem is the following:

    When a message is posted to the “monitoring” thread during a panel creation (panels are modless CDialog), the “monitoring” thread blocks on the Create(IDD); of the CDialog. More precisely in dlgcore.cpp, in method:
    BOOL CWnd::CreateDlgIndirect(LPCDLGTEMPLATE lpDialogTemplate, CWnd* pParentWnd, HINSTANCE hInst)
    on line:
    hWnd = ::CreateDialogIndirect(hInst, lpDialogTemplate, pParentWnd->GetSafeHwnd(), AfxDlgProc);

    This problem is very easy to reproduce if I use following code:
    ::PostThreadMessage ( monitoringThreadId, MSG_OpenPanel, 0, 0 );
    ::PostThreadMessage ( monitoringThreadId, MSG_ClosePanel, 0, 0 );

    In my log I can see the both post message. Only the first one handled and its processing stay blocked on the CDialog Create(IDD) method, as explained above.

    Thanks for your help.

  2. #2
    Join Date
    Jul 2005
    Location
    Netherlands
    Posts
    2,042

    Re: Problem: Creation of a modless CDialog in a thread.

    Why do you have a "monitoring" thread at all? Do all your user interface processing in the main thread. The only thing a worker thread should do with user interfaces is post messages to windows.
    Cheers, D Drmmr

    Please put [code][/code] tags around your code to preserve indentation and make it more readable.

    As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky

  3. #3
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,396

    Re: Problem: Creation of a modless CDialog in a thread.

    As D_Drmmr already pointed out you should move all the UI attributes into the main GUI thread.

    Besides:
    Quote Originally Posted by Cariboo42 View Post
    ... I use following code:
    Code:
    ::PostThreadMessage ( monitoringThreadId, MSG_OpenPanel, 0, 0 );
    ::PostThreadMessage ( monitoringThreadId, MSG_ClosePanel, 0, 0 );
    In my log I can see the both post message. Only the first one handled and its processing stay blocked ...
    You could only PostThreadMessage is the thread you were posting to had the message pump. "Worker" thread has no message pump. Only MFC so called "UI" thread has.
    You may want to look at the MDSN articles:
    PostThreadMessage Function (note its Remark section)
    AfxBeginThread
    as well as Using Worker Threads essay
    Victor Nijegorodov

  4. #4
    Join Date
    Jun 2011
    Location
    Antony (near Paris), France
    Posts
    11

    Re: Problem: Creation of a modless CDialog in a thread.

    Quote Originally Posted by D_Drmmr View Post
    Why do you have a "monitoring" thread at all? Do all your user interface processing in the main thread. The only thing a worker thread should do with user interfaces is post messages to windows.
    In fact, I develop an application with plug-ins and I decided to use Threads (and PostThreadMessages) for communication with my plug-ins. It also prevents the “main” thread to freeze due to time-consumer plug-ins.

    What I really want to understand is why a thread is blocking when it receives a message while it is creating a CDialog.

  5. #5
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,396

    Re: Problem: Creation of a modless CDialog in a thread.

    Quote Originally Posted by Cariboo42 View Post
    ...
    What I really want to understand is why a thread is blocking when it receives a message while it is creating a CDialog.
    Again:
    because a worker thread was not designed to handle thread messages. Just because it does not have message pump.
    Victor Nijegorodov

  6. #6
    Join Date
    Jun 2011
    Location
    Antony (near Paris), France
    Posts
    11

    Re: Problem: Creation of a modless CDialog in a thread.

    Quote Originally Posted by VictorN View Post
    You could only PostThreadMessage is the thread you were posting to had the message pump. "Worker" thread has no message pump. Only MFC so called "UI" thread has.
    I use CWinThread and everything works fine. I develop and use my application for about one month. I discovered this bug two days ago, when exiting the application, just after a panel creation.

    Then, after log analysis and two days of work, I found out that this bug occurs only when a message is posted the same time the thread was creating a CDialog.

    I think this can be due to a conflict when the message is added to the thread message pump and, at the same time, the CWinThread add the CDialog management to its message pump.

  7. #7
    Join Date
    Jun 2011
    Location
    Antony (near Paris), France
    Posts
    11

    Re: Problem: Creation of a modless CDialog in a thread.

    Quote Originally Posted by VictorN View Post
    Again:
    because a worker thread was not designed to handle thread messages. Just because it does not have message pump.
    Ok, we misunderstood. I use only CWinThread but I named this thread "working" thread because it has associated windows.
    Also the "working" thread works fine. The problem lies in the "monitoring" thread.

  8. #8
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,396

    Re: Problem: Creation of a modless CDialog in a thread.

    Quote Originally Posted by Cariboo42 View Post
    Ok, we misunderstood. I use only CWinThread but I named this thread "working" thread because it has associated windows.
    Also the "working" thread works fine. The problem lies in the "monitoring" thread.
    Did you read my post#3? Did you read the MSDN article AfxBeginThread?
    How did you create your "monitoring" thread?

    And again: why create a dialog in the secondary thread?
    Victor Nijegorodov

  9. #9
    Join Date
    Jun 2011
    Location
    Antony (near Paris), France
    Posts
    11

    Re: Problem: Creation of a modless CDialog in a thread.

    Sorry: ... it has NO associated windows.

  10. #10
    Join Date
    Jun 2011
    Location
    Antony (near Paris), France
    Posts
    11

    Re: Problem: Creation of a modless CDialog in a thread.

    Quote Originally Posted by VictorN View Post
    Did you read my post#3? Did you read the MSDN article AfxBeginThread?
    How did you create your "monitoring" thread?

    And again: why create a dialog in the secondary thread?
    I created the thread using the CreateThread method, to have a message pump and then to be able to use PostThreadMessage.

    My application mount/unmount modules and a need to create a thread for each module I mount. A module must be able to create dialog boxes.

  11. #11
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,396

    Re: Problem: Creation of a modless CDialog in a thread.

    Quote Originally Posted by Cariboo42 View Post
    I created the thread using the CreateThread method, to have a message pump ...
    Do you mean CWinThread::CreateThread or ::CreateThread API?
    How exactly? Could you show your code?
    Victor Nijegorodov

  12. #12
    Join Date
    Jun 2011
    Location
    Antony (near Paris), France
    Posts
    11

    Re: Problem: Creation of a modless CDialog in a thread.

    Code:
    // Main thread: Creation of MonitorThread.
    
        CMonitorThread* pMonitor = new CMonitorThread ();  // Derived from CWinThread.
        if ( pMonitor == NULL )
        {
            // Error management.
        }
    
        if ( pMonitor->CreateThread () == FALSE )
        {
            // Error management.
        }
    
        pMonitor->PostThreadMessage ( MSG_CreatePanel, 0, 0 );
    
    #ifdef DO_BUG
        Sleep ( 0 );
        pMonitor->PostThreadMessage ( MSG_DestroyPanel, 0, 0 );
    #endif
    
    // Monitor thread: Hanlde the MSG_CreatePanel.
    
    void CMonitorThread::OnCreatePanel ( WPARAM wParam, LPARAM lParam )
    {
        m_pPanel = new CMonotoringPanel ();
        if ( m_pPanel == NULL )
        {
            // Error management.
        }
    
        if ( m_pPanel->Create ( IDD ) == FALSE )
        {
            // Error management.
        }
    
        m_pPanel->ShowWindow ( SW_SHOW );
    }
    DO_BUG not defined:
    Works fine: The thread is created, the dialog box too.

    DO_BUG defined:
    Thread is created and both PostThreadMessage executed successfully (I checked the return value).
    First message (MSG_CreatePanel) has been received, but m_pPanel->Create(IDD) blocks, as explaind in my original post.

  13. #13
    Join Date
    Jul 2005
    Location
    Netherlands
    Posts
    2,042

    Re: Problem: Creation of a modless CDialog in a thread.

    Quote Originally Posted by Cariboo42 View Post
    In fact, I develop an application with plug-ins and I decided to use Threads (and PostThreadMessages) for communication with my plug-ins. It also prevents the “main” thread to freeze due to time-consumer plug-ins.
    IMO this is a bad design. Multi-threaded code is hard to debug and it's easy to introduce errors if a programmer doesn't know how to do MT programming correctly. When you have little or no control over some part of the code that will be executed by your program, you should try to prevent these problems. Thus, if the plug-ins need to create windows, let them do it in the main thread. If a plug-in has time-consuming operations, it should create its own worker thread to prevent the application from becoming non-responsive.
    Quote Originally Posted by Cariboo42 View Post
    What I really want to understand is why a thread is blocking when it receives a message while it is creating a CDialog.
    Maybe this will help: http://support.microsoft.com/kb/183116
    Cheers, D Drmmr

    Please put [code][/code] tags around your code to preserve indentation and make it more readable.

    As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky

  14. #14
    Join Date
    Jun 2011
    Location
    Antony (near Paris), France
    Posts
    11

    Re: Problem: Creation of a modless CDialog in a thread.

    Quote Originally Posted by D_Drmmr View Post
    Thanks. It helps to understand how dialog message pump works and the problems inherent to such design when using in threads. But this concerns essentially modal dialogs. IMO, it should work with modless dialogs, but what I also understand is that modless CDialog creation is not multi-thread safe regarding to PostThreadMessage.

    Quote Originally Posted by D_Drmmr View Post
    IMO this is a bad design. Multi-threaded code is hard to debug and it's easy to introduce errors
    Indeed, it seems to be a bad design to create windows in separate threads. So I’ll redesign my application that way.
    But I do not agree with the fact that MT programming is hard to debug. It’s like everything else: It requires being rigorous.

  15. #15
    Join Date
    Jul 2005
    Location
    Netherlands
    Posts
    2,042

    Re: Problem: Creation of a modless CDialog in a thread.

    Quote Originally Posted by Cariboo42 View Post
    Thanks. It helps to understand how dialog message pump works and the problems inherent to such design when using in threads. But this concerns essentially modal dialogs. IMO, it should work with modless dialogs, but what I also understand is that modless CDialog creation is not multi-thread safe regarding to PostThreadMessage.
    No, that page is not limited to modal dialogs. It talks about modal behavior and explicitly mentions moving or resizing the window as examples. I'm not sure, but it could be that dialog creation is modal behavior and therefore, the posted thread message is lost.
    Quote Originally Posted by Cariboo42 View Post
    But I do not agree with the fact that MT programming is hard to debug. It’s like everything else: It requires being rigorous.
    That's the first time I've heard anyone say debugging MT code is not hard. By its very nature MT-related bugs are not strictly reproducible, which by itself makes them hard to debug in my book. Also AFAIK, VS does not offer much support for debugging MT-related issues, unlike the tools offered to track memory leaks, iterator/bounds validation, memory values set by debug heap allocator, etc.
    So, I'm curious what makes you say that MT programming is not hard to debug? Which tools/methods do you use?
    Cheers, D Drmmr

    Please put [code][/code] tags around your code to preserve indentation and make it more readable.

    As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured