Accessing MFC objects in other threads
Erik van der Goot -- erik.van-der-goot@jrc.it Tuesday, February 27, 1996 Hi there, In a multithreading application it is suggested by Microsoft that a thread can only access MFC objects that it created. (Multiprogramming: Programming tips). However, after messing around, probably making some mistakes, I could not get my worker thread to update a window (CPropertyPage) in the main thread, so I just passed the pointer to the workerthread (and cast it to CDialog in the process) and now I am happily updating my window by doing a pDlg->SetDlgItemInt(). Did I misundertand the docs? Am I just lucky?? I am in the process of designing a rather large app and I am trying to understand the implication of various things before I launch into the real project. Thanks Erik
Mike Blaszczak -- mikeblas@interserv.com Friday, March 01, 1996 On Tue, 27 Feb 96, Erik van der Gootwrote: >In a multithreading application it is suggested by Microsoft that a thread >can only access MFC objects that it created. (Multiprogramming: Programming >tips). >However, after messing around, probably making some mistakes, I could not >get my worker thread to update a window (CPropertyPage) in the main thread, >so I just passed the pointer to the workerthread (and cast it to CDialog in >the process) and now I am happily updating my window by doing a >pDlg->SetDlgItemInt(). >Did I misundertand the docs? No, you misunderstood threading. All that SetDlgItemInt() does is send a message to the m_hWnd of the pDlg that you're working with. This doesn't violate any rules--you're not relying on MFC's thread-local map for a mapping between a m_hWnd and a CWnd* that your thread doesn't own. Instead, you're blocking the thread that calls SetDlgItemInt() and asking the system to let the thread that owns the target window run. When it is done processing the message, it suspends (or, eventually, goes and does something else) and then your calling thread is resumed since it has the return value. So, in essence, the code that surrounds your call to SetDlgItemInt() is wasting time. It's stalling one thread to resume another. This just adds to the overhead of your application... you're wasting time switching tasks when you could be getting real work done. >I am in the process of >designing a rather large app and I am trying to understand the implication >of various things before I launch into the real project. You owe it to yourself to read up a little bit more on threading in Windows... even without MFC involved. .B ekiM -- TCHAR szDisc[] = _T("These words are my own; I do not speak for Microsoft.");
Erik van der Goot -- erik.van-der-goot@jrc.it Sunday, March 03, 1996 At 01:20 01/03/96 -0800, you wrote: >On Tue, 27 Feb 96, Erik van der Gootwrote: > >>In a multithreading application it is suggested by Microsoft that a thread >>can only access MFC objects that it created. (Multiprogramming: Programming >>tips). > >>However, after messing around, probably making some mistakes, I could not >>get my worker thread to update a window (CPropertyPage) in the main thread, >>so I just passed the pointer to the workerthread (and cast it to CDialog in >>the process) and now I am happily updating my window by doing a >>pDlg->SetDlgItemInt(). > >>Did I misundertand the docs? > >No, you misunderstood threading. All that SetDlgItemInt() does is send a >message to the m_hWnd of the pDlg that you're working with. This doesn't >violate any rules--you're not relying on MFC's thread-local map for a mapping >between a m_hWnd and a CWnd* that your thread doesn't own. I'm sorry Mike, but I don't quite get that. The 'method' that I am invoking definitely belongs to an 'object' that the invoking thread has not created. What goes on behind the scenes is a different matter (although admittedly rather important :-)). When I pass the pDlg to my thread, the m_hWnd of the windows is still very much null. This is one of the 'problems' that I had, because I initialize the threads from the constructor of the CPropertySheet that contains the CPropertyPages that I want to access. By the time I call pDlg->SetDlgItemInt the window does of course exist. But where does the m_hWnd now live?? I can test for it at that time in my thread and it yields the proper window. But I guess that what you are saying is that as long as I just send messages it will work. Right? > >Instead, you're blocking the thread that calls SetDlgItemInt() and asking the >system to let the thread that owns the target window run. When it is done >processing the message, it suspends (or, eventually, goes and does something >else) and then your calling thread is resumed since it has the return value. > >So, in essence, the code that surrounds your call to SetDlgItemInt() is >wasting time. It's stalling one thread to resume another. This just adds to >the overhead of your application... you're wasting time switching tasks when >you could be getting real work done. Ok, don't get me wrong, the SetDlgItemInt was very much a quick and dirty test to see what would happen. To simply update a window I would rather use PostMessage. However, I have a real need for something similar, where I need to get at some information entered by the user on one of the pages. Without that info, there is not much that the thread can do. As a matter of fact, I got stuck, (as the docs predicted) a few days ago when I tried to implement a function to get the data from a page in my wizard. Using an event I signal to the waiting (but initialized thread) that my user-info is ready and I call a function of the page to get it. Alas, I get as far as executing the first line which is (not surprisingly) 'UpdateData' and here it stops... >You owe it to yourself to read up a little bit more on threading in >Windows... even without MFC involved. Thanks Mike, but perhaps I will not react to this in public :-) :-) Ciao Erik
| Вернуться в корень Архива |