terminating thread in button on-event
-
Hi Everyone, I implemente a thread in a MFC application that can be started and stopped through 2 buttons. My problem: After i click the Stop button, the while-loop doesn't break, meaning that WaitForSingleObject does never return WAIT_OBJECT_0. How can i terminate a thread like this using wait for single object? I noticed that some calls to PeekMessage inside the while loop make WaitForSingleObject return WAIT_OBJECT_0. I really don't understand why this isn't working! Please can anybody help?? Jason //------------------------------------------------------------------------- void CAnyDlg::OnStart() { // declarations DWORD dwId; // start the thread m_bThread=true; if(m_hThread=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)StartThread,(LPVOID)this,0,&dwId)) } //------------------------------------------------------------------------- void CAnyDlg::OnStop() { MSG msg; while(::WaitForSingleObject(m_hThread,100)!=WAIT_OBJECT_0)) { m_bThread=false; } } //------------------------------------------------------------------------- DWORD CAnyDlg::StartThread(LPVOID lpParam) { ((CAnyDlg*)lpParam)->Thread(); return 0; } //------------------------------------------------------------------------- void CAnyDlg::Thread() { while(m_bThread) { m_cstaAnyStatic.SetWindowText("Test"); } } //-------------------------------------------------------------------------
-
Hi Everyone, I implemente a thread in a MFC application that can be started and stopped through 2 buttons. My problem: After i click the Stop button, the while-loop doesn't break, meaning that WaitForSingleObject does never return WAIT_OBJECT_0. How can i terminate a thread like this using wait for single object? I noticed that some calls to PeekMessage inside the while loop make WaitForSingleObject return WAIT_OBJECT_0. I really don't understand why this isn't working! Please can anybody help?? Jason //------------------------------------------------------------------------- void CAnyDlg::OnStart() { // declarations DWORD dwId; // start the thread m_bThread=true; if(m_hThread=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)StartThread,(LPVOID)this,0,&dwId)) } //------------------------------------------------------------------------- void CAnyDlg::OnStop() { MSG msg; while(::WaitForSingleObject(m_hThread,100)!=WAIT_OBJECT_0)) { m_bThread=false; } } //------------------------------------------------------------------------- DWORD CAnyDlg::StartThread(LPVOID lpParam) { ((CAnyDlg*)lpParam)->Thread(); return 0; } //------------------------------------------------------------------------- void CAnyDlg::Thread() { while(m_bThread) { m_cstaAnyStatic.SetWindowText("Test"); } } //-------------------------------------------------------------------------
jason99 wrote: ...the while-loop doesn't break, meaning that WaitForSingleObject does never return WAIT_OBJECT_0. Nor should it. When the Stop button is clicked, you are waiting 1/10 of a second for the secondary thread object to become signaled. Since there is no code in place to signal it,
WAIT_TIMEOUT
is returned. Once that happens,m_bThread
is set tofalse
, which should cause the loop inCAnyDlg::Thread()
to stop, but does nothing for the loop inCAnyDlg::OnStop()
, which only stops onceWAIT_OBJECT_0
is returned.
Five birds are sitting on a fence. Three of them decide to fly off. How many are left?
-
jason99 wrote: ...the while-loop doesn't break, meaning that WaitForSingleObject does never return WAIT_OBJECT_0. Nor should it. When the Stop button is clicked, you are waiting 1/10 of a second for the secondary thread object to become signaled. Since there is no code in place to signal it,
WAIT_TIMEOUT
is returned. Once that happens,m_bThread
is set tofalse
, which should cause the loop inCAnyDlg::Thread()
to stop, but does nothing for the loop inCAnyDlg::OnStop()
, which only stops onceWAIT_OBJECT_0
is returned.
Five birds are sitting on a fence. Three of them decide to fly off. How many are left?
OK, that is right. The first call to WaitForSingle object will surely return WAIT_TIMEOUT. But when the bool is switched, the loop in CAnyDlg::Thread() stops. This means that the created thread will terminate sometime later. From this point on, a continous call to WaitForSingleObject should return WAIT_OBJECT_0 after some time. But that doesn't happen. Tha fact that concerns me is that the code works if i take away the SetWindowText() in the thread or i i call PeekMessage in the WaitForSingleObject loop...this must have something to do with the message queue...
-
Hi Everyone, I implemente a thread in a MFC application that can be started and stopped through 2 buttons. My problem: After i click the Stop button, the while-loop doesn't break, meaning that WaitForSingleObject does never return WAIT_OBJECT_0. How can i terminate a thread like this using wait for single object? I noticed that some calls to PeekMessage inside the while loop make WaitForSingleObject return WAIT_OBJECT_0. I really don't understand why this isn't working! Please can anybody help?? Jason //------------------------------------------------------------------------- void CAnyDlg::OnStart() { // declarations DWORD dwId; // start the thread m_bThread=true; if(m_hThread=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)StartThread,(LPVOID)this,0,&dwId)) } //------------------------------------------------------------------------- void CAnyDlg::OnStop() { MSG msg; while(::WaitForSingleObject(m_hThread,100)!=WAIT_OBJECT_0)) { m_bThread=false; } } //------------------------------------------------------------------------- DWORD CAnyDlg::StartThread(LPVOID lpParam) { ((CAnyDlg*)lpParam)->Thread(); return 0; } //------------------------------------------------------------------------- void CAnyDlg::Thread() { while(m_bThread) { m_cstaAnyStatic.SetWindowText("Test"); } } //-------------------------------------------------------------------------
-
OK, that is right. The first call to WaitForSingle object will surely return WAIT_TIMEOUT. But when the bool is switched, the loop in CAnyDlg::Thread() stops. This means that the created thread will terminate sometime later. From this point on, a continous call to WaitForSingleObject should return WAIT_OBJECT_0 after some time. But that doesn't happen. Tha fact that concerns me is that the code works if i take away the SetWindowText() in the thread or i i call PeekMessage in the WaitForSingleObject loop...this must have something to do with the message queue...
If this secondary thread's handle is closed while the wait is still pending,
WaitForSingleObject()
's behavior is undefined. Have you seen these two articles: http://www.flounder.com/workerthreads.htm http://www.flounder.com/uithreads.htm -
Hi Everyone, I implemente a thread in a MFC application that can be started and stopped through 2 buttons. My problem: After i click the Stop button, the while-loop doesn't break, meaning that WaitForSingleObject does never return WAIT_OBJECT_0. How can i terminate a thread like this using wait for single object? I noticed that some calls to PeekMessage inside the while loop make WaitForSingleObject return WAIT_OBJECT_0. I really don't understand why this isn't working! Please can anybody help?? Jason //------------------------------------------------------------------------- void CAnyDlg::OnStart() { // declarations DWORD dwId; // start the thread m_bThread=true; if(m_hThread=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)StartThread,(LPVOID)this,0,&dwId)) } //------------------------------------------------------------------------- void CAnyDlg::OnStop() { MSG msg; while(::WaitForSingleObject(m_hThread,100)!=WAIT_OBJECT_0)) { m_bThread=false; } } //------------------------------------------------------------------------- DWORD CAnyDlg::StartThread(LPVOID lpParam) { ((CAnyDlg*)lpParam)->Thread(); return 0; } //------------------------------------------------------------------------- void CAnyDlg::Thread() { while(m_bThread) { m_cstaAnyStatic.SetWindowText("Test"); } } //-------------------------------------------------------------------------
Aha! m_cstaAnyStatic.SetWindowText causes a
WM_SETTEXT
message to be sent to the message queue. However, while in the loop in CAnyDlg::Stop, the UI thread can't process the message (this assumes that the static control and the dialog box were created by the same thread and hence share that thread's message queue). You're effectively deadlocked. It's typically a bad idea to directly modify any controls on the UI thread from a worker thread. It's better to define a custom message and post (not send) messages to the window to effect any changes in UI state.PostMessage
just queues up the message, then returns;SendMessage
blocks until the message is received by the window procedure, processed, and a response generated (either by returning from the window procedure, or by callingReplyMessage
). -
Aha! m_cstaAnyStatic.SetWindowText causes a
WM_SETTEXT
message to be sent to the message queue. However, while in the loop in CAnyDlg::Stop, the UI thread can't process the message (this assumes that the static control and the dialog box were created by the same thread and hence share that thread's message queue). You're effectively deadlocked. It's typically a bad idea to directly modify any controls on the UI thread from a worker thread. It's better to define a custom message and post (not send) messages to the window to effect any changes in UI state.PostMessage
just queues up the message, then returns;SendMessage
blocks until the message is received by the window procedure, processed, and a response generated (either by returning from the window procedure, or by callingReplyMessage
).Good catch!! The post vs. send message problem is common, but is sometimes hidden in the problem description.
Five birds are sitting on a fence. Three of them decide to fly off. How many are left?
-
Good catch!! The post vs. send message problem is common, but is sometimes hidden in the problem description.
Five birds are sitting on a fence. Three of them decide to fly off. How many are left?