Waiting in GUI till thread ends
I have a dialog that does a certain operation in a thread. I create the thread upon pressing a button.
From the button handler I want to wait till the thread ends.
If I wait till the thread turns on a flag, the GUI is freeze.
What is the optimal way to do it ?
Thanks.
Re: Waiting in GUI till thread ends
Quote:
Originally Posted by zvivered
I have a dialog that does a certain operation in a thread. I create the thread upon pressing a button.
From the button handler I want to wait till the thread ends.
If I wait till the thread turns on a flag, the GUI is freeze.
What is the optimal way to do it ?
Not sure what you really want. Without a worker thread, your GUI would wait for the operation to complete (and hence freeze). You normally introduce a worker thread so that your GUI does not have to wait. Now you say you want to wait - so why the thread? What do you mean by "waiting" without freezing? What exactly is the behaviour you are expecting?
Re: Waiting in GUI till thread ends
First of all, is there a need to wait for the thread operation inside the Button handler? Normally, u create a worker thread to perform certain operations so that your GUI can continue to receive user action.
Re: Waiting in GUI till thread ends
Quote:
Originally Posted by gstercken
Not sure what you really want. Without a worker thread, your GUI would wait for the operation to complete (and hence freeze). You normally introduce a worker thread so that your GUI does not have to wait. Now you say you want to wait - so why the thread? What do you mean by "waiting" without freezing? What exactly is the behaviour you are expecting?
Thank you for your answer:
This is what I'm trying to do in the button handler:
void CThreadDlg::OnButton1()
{
// TODO: Add your control notification handler code here
CreateThread (0,1024*10,Acquire,this,0,&AcquireId);
while (!ThreadEnd)
Sleep(10);
}
The while (with sleep) causes the GUI to freeze. The window can not be moved.
What should I do ?
Re: Waiting in GUI till thread ends
The while loop will keep calling Sleep() until the thread is finished, so no messages are processed, that's why your application freezes. I don't understand what you'd like to happen while the thread is running
Re: Waiting in GUI till thread ends
Quote:
Originally Posted by zvivered
This is what I'm trying to do in the button handler: The while (with sleep) causes the GUI to freeze.
Well, the code shows what you're currently doing, not what you want to happen. It's pretty obvious that calling Sleep() in your main thread freezes the UI.
Quote:
Originally Posted by zvivered
What should I do ?
As said above: What would you like to happen? It's still unclear how you expect your app to behave.
Re: Waiting in GUI till thread ends
Quote:
Originally Posted by gstercken
Well, the code shows what you're currently doing, not what you want to happen. It's pretty obvious that calling Sleep() in your main thread freezes the UI.
As said above: What would you like to happen? It's still unclear how you expect your app to behave.
Thank you for your reply.
While the handler waits for the thread to end I want to be able to press other buttons in my dialog. This is not possible now. My main thread freezes the UI.
Re: Waiting in GUI till thread ends
Quote:
Originally Posted by EoF
The while loop will keep calling Sleep() until the thread is finished, so no messages are processed, that's why your application freezes. I don't understand what you'd like to happen while the thread is running
Thank you for your reply.
While the thread is runnig I want to press other buttons in my dialog.
But at the same time I want to wait in the handler till the thread ends.
I want that messages will continue to be processed.
Re: Waiting in GUI till thread ends
Quote:
Originally Posted by zvivered
While the handler waits for the thread to end I want to be able to press other buttons in my dialog. This is not possible now. My main thread freezes the UI.
Well, if that's the only requirement: Just remove the loop with the Sleep().
Re: Waiting in GUI till thread ends
Quote:
Originally Posted by gstercken
Well, if that's the only requirement: Just remove the loop with the Sleep().
I can't. I want that after the thred ends, the handler will do something else.
Thanks.
Re: Waiting in GUI till thread ends
Quote:
Originally Posted by zvivered
I can't. I want that after the thred ends, the handler will do something else.
The handler's purpose is to handle the button click. What else do you want it to do? Whatever that is - wouldn't it be better to put that into the thread function?
Re: Waiting in GUI till thread ends
If I understand correctly (which I am not sure) you want to be able to interact with the rest of your application except for the button that launched the new thread. If this is the case, you should disable the button when you create the thread, remove the while loop and reenable the button when the thread has finished.
Re: Waiting in GUI till thread ends
Give your dialog's hwnd to the thread. When the worker thread ends, have it post a message to your dialog to tell it that it's done.
Make your own message, e.g.
#define WM_MYTHREADENDED WM_USER
Then at the end of your worker thread
::PostMessage(hwndDialog, WM_MYTHREADENDED, 0, 0);
And then make a method in your dialog class called OnThreadEnded().
Then in your dialog's message map:
ON_MESSAGE(WM_MYTHREADENDED, OnThreadEnded)
And your method will get called when the thread is done. Does that help?
Re: Waiting in GUI till thread ends
Quote:
Originally Posted by torfil
.... Does that help?
It should help: it's a great answer.
Just to be clear, your button click handler should do nothing except start the thread and then exit. The thread then posts the WM_MYTHREADENDED message when it's done, and your message handler for WM_MYTHREADENDED should then perform the steps that you originally wanted to do in your original button click handler (i.e., "the handler will do something else").
If you want to prevent the user from re-clicking the button while the thread is running (for example, maybe it would be a bad thing to try to acquire again while another acquisition is in-process), then you can disable the button in the button click handler and re-enable it in the handler for WM_MYTHREADENDED. Use EnableWindow(FALSE). For example, assuming that your dialog has a member variable of type "CButton" for the button, named m_ctlButtonAcquire:
Code:
void CThreadDlg::OnButton1()
{
CreateThread (0,1024*10,Acquire,this,0,&AcquireId);
m_ctlButtonAcquire.EnableWindow(FALSE);
}
LRESULT CThreadDlg::OnWmThreadEnded(LPARAM lParam, WPARAM wParam)
{
// TODO: Add the steps that you wanted to do in the
// original button click handler, i.e., "the handler will do
// something else"
m_ctlButtonAcquire.EnableWindow(TRUE);
return 0L;
}
Mike
Re: Waiting in GUI till thread ends
I solved the problem:
while (GetMessage(&msg,NULL,NULL,NULL) && !ThreadEnd)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
//Do someting ...
This works great (I Think).