Get User Actions While Background Thread Executes
-
Newbie Question: I have a C/C++ Dialog-based app using Visual Sutdio 6.0. I begin and intensive background processing task using, AfxBeginThread with THREAD_PRIORITY_BELOW_NORMAL. All user actions seem to be suspended until this processing task completes. I would like user actions, such as repositioning the Dialog and clicking buttons to work immediately. I have a periodic update on the screen, UpdateData(), to inform the User of progress of the background task and tried placing a Sleep() statement in their but that does not seem to work. Any help would be very much appreciated.:)
-
Newbie Question: I have a C/C++ Dialog-based app using Visual Sutdio 6.0. I begin and intensive background processing task using, AfxBeginThread with THREAD_PRIORITY_BELOW_NORMAL. All user actions seem to be suspended until this processing task completes. I would like user actions, such as repositioning the Dialog and clicking buttons to work immediately. I have a periodic update on the screen, UpdateData(), to inform the User of progress of the background task and tried placing a Sleep() statement in their but that does not seem to work. Any help would be very much appreciated.:)
If you are doing the intensive background processing in your worker thread, what is your main thread doing during this time? Are you just waiting for the worker thread to complete? If the main thread just exits the current message handler, and continues to execute the main message loop, then it should be able to handle new messages (user input) with no problems. Post the code for how you are creating the thread - it should make things a bit clearer from this end... Dave
-
If you are doing the intensive background processing in your worker thread, what is your main thread doing during this time? Are you just waiting for the worker thread to complete? If the main thread just exits the current message handler, and continues to execute the main message loop, then it should be able to handle new messages (user input) with no problems. Post the code for how you are creating the thread - it should make things a bit clearer from this end... Dave
Dave, Thank-you for response. Here is the multi-step approach I use to run a background thread that can update Dialog class variables during it's execution. === STEP 1 Use AfxBeginThread to run a function, zdisplay() CWinThread *pThread = AfxBeginThread( &zdisplay, this->m_hWnd, THREAD_PRIORITY_BELOW_NORMAL ); ASSERT( NULL != pThread ); ===STEP 2 Use zdisplay() function to endlessly loop and send a message, WM_APP_UPDATE_DLG. UINT CCryptoDlg::zdisplay( LPVOID pParam ) { int xx=1; do { ::SendMessage( (HWND)pParam, WM_APP_UPDATE_DLG, (WPARAM)buf, 0 ); if (xx == 1) { Sleep(1000); } } while(TRUE); /*end do statement*/ return 0; } /*end zdisplay() function*/ ===STEP 3 Define message WM_APP_UPDATE_DLG to run function OnUpdateDialog(). ON_MESSAGE( WM_APP_UPDATE_DLG, OnUpdateDialog ) ===STEP 4 The code in OnUpdateDialog () is the intensive background task that seems to be disallowing the main dialog to respond to user I/O. Much thanks, Robert :)
-
Dave, Thank-you for response. Here is the multi-step approach I use to run a background thread that can update Dialog class variables during it's execution. === STEP 1 Use AfxBeginThread to run a function, zdisplay() CWinThread *pThread = AfxBeginThread( &zdisplay, this->m_hWnd, THREAD_PRIORITY_BELOW_NORMAL ); ASSERT( NULL != pThread ); ===STEP 2 Use zdisplay() function to endlessly loop and send a message, WM_APP_UPDATE_DLG. UINT CCryptoDlg::zdisplay( LPVOID pParam ) { int xx=1; do { ::SendMessage( (HWND)pParam, WM_APP_UPDATE_DLG, (WPARAM)buf, 0 ); if (xx == 1) { Sleep(1000); } } while(TRUE); /*end do statement*/ return 0; } /*end zdisplay() function*/ ===STEP 3 Define message WM_APP_UPDATE_DLG to run function OnUpdateDialog(). ON_MESSAGE( WM_APP_UPDATE_DLG, OnUpdateDialog ) ===STEP 4 The code in OnUpdateDialog () is the intensive background task that seems to be disallowing the main dialog to respond to user I/O. Much thanks, Robert :)
What's happening is your background thread isn't doing the processing at all. It is sending a message to the main thread, telling it to do the operation. Since the main thread is now busy doing the intensive operation, it obviously cannot respond to user input. In addition, SendMessage() is a blocking call, so your worker thread is suspended during this as well. Change the intensive processing to happen inside the worker thread, and it should post (not send) a message to the main thread whenever it needs to update the display. This will keep the main thread free to process user input, but still only have one thread modifying the display at a time. Dave
-
What's happening is your background thread isn't doing the processing at all. It is sending a message to the main thread, telling it to do the operation. Since the main thread is now busy doing the intensive operation, it obviously cannot respond to user input. In addition, SendMessage() is a blocking call, so your worker thread is suspended during this as well. Change the intensive processing to happen inside the worker thread, and it should post (not send) a message to the main thread whenever it needs to update the display. This will keep the main thread free to process user input, but still only have one thread modifying the display at a time. Dave
Hi Dave, Thank-you for your response. I think I'm getting it. zdisplay() is clearly a worker thread since it is so-started by AfxBeginThread(). I assumed (badly) that since OnUpdateDialog() function (the intensive processing) was started from a message sent BY the zdisplay() function that it too was of the 'worker' variety. Clearly you are correct, but what tells you that OnUpdateDialog() is considered a 'main' thread rather than a 'worker' thread? Sorry for all the dumb questions. Thank-you very much, Robert :)
-
Hi Dave, Thank-you for your response. I think I'm getting it. zdisplay() is clearly a worker thread since it is so-started by AfxBeginThread(). I assumed (badly) that since OnUpdateDialog() function (the intensive processing) was started from a message sent BY the zdisplay() function that it too was of the 'worker' variety. Clearly you are correct, but what tells you that OnUpdateDialog() is considered a 'main' thread rather than a 'worker' thread? Sorry for all the dumb questions. Thank-you very much, Robert :)
Windows are associated with the thread in which they are created. When you send or post a message to a window handle, it will be processed by the thread that owns that window (which may be the same thread). In addition, since worker threads do not have a message pump, they cannot process any messages. Take a look through some of the thread articles, particularly the ones talking about worker threads vs. user interface threads if you are interested. Dave
-
Windows are associated with the thread in which they are created. When you send or post a message to a window handle, it will be processed by the thread that owns that window (which may be the same thread). In addition, since worker threads do not have a message pump, they cannot process any messages. Take a look through some of the thread articles, particularly the ones talking about worker threads vs. user interface threads if you are interested. Dave
Hi Dave, Thanks again. I wrote a quick little test program to experiment with this and it works just like you indicated - no surprize. I found PostMessage() in the Win32 SDK and will implement that as well. It looks like it takes the same parameters. Thanks for helping me through this. I'm an old C warhorse and C++ and MFC are new to me. :)
-
Hi Dave, Thanks again. I wrote a quick little test program to experiment with this and it works just like you indicated - no surprize. I found PostMessage() in the Win32 SDK and will implement that as well. It looks like it takes the same parameters. Thanks for helping me through this. I'm an old C warhorse and C++ and MFC are new to me. :)
Not a problem Dave
-
Newbie Question: I have a C/C++ Dialog-based app using Visual Sutdio 6.0. I begin and intensive background processing task using, AfxBeginThread with THREAD_PRIORITY_BELOW_NORMAL. All user actions seem to be suspended until this processing task completes. I would like user actions, such as repositioning the Dialog and clicking buttons to work immediately. I have a periodic update on the screen, UpdateData(), to inform the User of progress of the background task and tried placing a Sleep() statement in their but that does not seem to work. Any help would be very much appreciated.:)
who used visual basic knows that it has a holly function : DoEvents() it processes events while working ! int i=0; while(1) { i++; DoEvents(); } this is the C++ version : bool DoEvents() { MSG msg; while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) == TRUE) { if (GetMessage(&msg, NULL, 0, 0) ) { TranslateMessage(&msg); DispatchMessage(&msg); } else { return TRUE; } } return 0; } //rate me or hate me I am the mighty keeper of the book on knowledge . Contact me to get your copy .
-
who used visual basic knows that it has a holly function : DoEvents() it processes events while working ! int i=0; while(1) { i++; DoEvents(); } this is the C++ version : bool DoEvents() { MSG msg; while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) == TRUE) { if (GetMessage(&msg, NULL, 0, 0) ) { TranslateMessage(&msg); DispatchMessage(&msg); } else { return TRUE; } } return 0; } //rate me or hate me I am the mighty keeper of the book on knowledge . Contact me to get your copy .
Thanks TomKat!:)