question

drjackool-3839 avatar image
0 Votes"
drjackool-3839 asked RLWA32-6355 edited

multi-threading and UI in MFC

hi
If we call WindowUpdate function or other window managing messages of a same window in several threads is safe?

For example in main thread creates the main frame window and in a worker threads (more than one) we call theApp.m_pMainWnd->UpdateWindow or for a child window like list view ctrl call RedrawItem. (to show the user progress of current operation in threads)

If is not safe what is safe way? I know can use a timer on main window or using PostMessage but is there a better way?

Thanks

c++
· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

I'd expect InvalidateRect to be OK, but not UpdateWindow.

0 Votes 0 ·
RLWA32-6355 avatar image
0 Votes"
RLWA32-6355 answered

Windows have thread affinity. Manipulating a window from a thread other than the one on which it was created is inherently unsafe. I'm not aware of any simple answers. In addition to what you've mentioned, Raymond Chen's blog at Using contexts to return to a COM apartment later discusses using COM contexts to marshal non-COM functions to a UI thread.


5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

GuidoFranzke avatar image
1 Vote"
GuidoFranzke answered RLWA32-6355 edited

Hello,
you should not use UpdateWindow etc from within the thread.
I suggest, you should send a WM_COPYDATA message to your main window:

  // in your thread:
    
 COPYDATASTRUCT cpdata;
 cpdata.cbData = 99; // function identifier
 cpdata.dwData = 1; // my type identifier for the message e.g. 1 for UpdateWindow()
 cpdata.lpData = (PVOID)&data; // data if needed (or NULL)
    
 AfxGetMainWnd()->SendMessage(WM_COPYDATA, (WPARAM)0, (LPARAM)(LPVOID)&cpdata);


 // in your mainframe:

 BOOL CMainFrame::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)
 {
   if (pCopyDataStruct && pWnd == NULL && pCopyDataStruct->cbData == 99)
   {
     if (pCopyDataStruct->dwData == 1)
     {
        UpdateWindow();
     }
     //else if ... other type identifiers
     return TRUE
   }
    
   return CMDIFrameWndEx::OnCopyData(pWnd, pCopyDataStruct);
 }

The mainframe window will handle the messages when it is ready to handle them.
Regards, Guido





· 2
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Yes, this is a way too.

0 Votes 0 ·

Don't forget that cross-thread use of SendMessage causes the sending thread to block, creating the possibility of deadlock.

1 Vote 1 ·