|
Hi all,
I am creating a dialog app that has a button. When the button is pressed, in OnButton function of the dialog's cpp it creates a thread (I am using CreateThread() )that runs some task. I will have to wait for the task's completion by watching the thread's termination via WaitForSingleObject(hThread, INFINITE) there. Now, the thread 's execution may take seconds so the WaitForSingleObject() would actually block windows messages and the dialog window "freezes" during the time. I'd love to NOT have the dialog frozen but simply have the button disabled during the thread task's execution. As now I have two ways in mind:
1. Use Timer and places the thread creation process in the Timer's function instead. Disabling and re-enabling button can be directly done in the function.
2. Create a main thread that does the thread creation process. The main thread will disable and enable the button via PostMessage() .
I am just wondering what an appropriate approach would be to solve this problem?
Thanks in advance,
Best Regards,
Johnny
|
|
|
|
|
Why not do something simple like:
1. disable button
2. create and start thread
3. when thread completes it posts a message to your dialog where you enable the button
Sort of like your (2), but guarantees the button disabled when thread starts. The dialog can still receive timer messages if you need a watchdog.
Peter
"Until the invention of the computer, the machine gun was the device that enabled humans to make the most mistakes in the smallest amount of time."
|
|
|
|
|
Thanks a lot for the reply, Peter,
This would work partially. But I think this is will not solve the frozen dialog window problem I am having, as long as I use WaitForSingleObject() or WaitForMultipleObjects() (multiple tasks executed at once) in my dialog's cpp. I have to wait until all the thread are terminated to calculate the total execution time. That's why I thought about putting WaitForSingleObject() or WaitForMultipleObjects() in another thread or Timer which creates the (threaded) tasks, without blocking dialog's window messages.
I hope it makes sense.
Thanks again,
Best Regards,
Johnny
|
|
|
|
|
J.B. wrote: I will have to wait for the task's completion by watching the thread's termination via WaitForSingleObject(hThread, INFINITE) there.
Then there's really no point in having a second thread if you're still doing things in serial. The implementation misses the point of multithreading.
I suggest you spawn the thread as you already do, but continue after the thread is created and don't wait for it.
When the thread has finished its task it should post a message to the main thread/window to inform the main thread that it has finished. In the message handler you can then enable your button again and do whatever you have to do in order to clean up.
"It's supposed to be hard, otherwise anybody could do it!" - selfquote "High speed never compensates for wrong direction!" - unknown
|
|
|
|
|
Roger Stoltz wrote: Then there's really no point in having a second thread if you're still doing things in serial. The implementation misses the point of multithreading.
Agreed. It's amazing how many folks start doing Windows development synchronously.
"Approved Workmen Are Not Ashamed" - 2 Timothy 2:15
"Judge not by the eye but by the heart." - Native American Proverb
|
|
|
|
|
DavidCrow wrote: Agreed. It's amazing how many folks start doing Windows development synchronously.
I know what you mean, and it is an issue. I don’t find is surprising however; its natural to think sequentially and if you're used to writing console applications even more so.
Steve
|
|
|
|
|
That's what I was trying to describe - you did a better job!
Peter
"Until the invention of the computer, the machine gun was the device that enabled humans to make the most mistakes in the smallest amount of time."
|
|
|
|
|
Roger Stoltz wrote: Then there's really no point in having a second thread if you're still doing things in serial. The implementation misses the point of multithreading.
While true to a large degree this is not always the case. For example, you may be doing a long task and want to keep the UI responsive or even if the UI is disabled you still want the application to repaint itself while the task is in progress. You could scatter message pumps throughout the long task but this is not always possible and even when it is it may not be practical.
Steve
|
|
|
|
|
I admit I have used ::MsgWaitForMultipleObjects(...) in the way you're referring to a couple of times. But those cases were very specific.
You can also get in trouble with re-entrancy with Chaos and Mayhem following if you're not careful. There was nothing in J.B.'s post that implied to me that this could be such a rare case, that's why I suggested the most common, straight-forward and less error prone way to do it.
I also think you're missing my point Steve.
I wrote that "the implementation misses the point of multithreading" referring to J.B.'s call to ::WaitForSingleObject(...) blocking the main thread during the wait. In that situation he would actually gain on doing the worker thread task in the main thread.
I intentionally phrased it that way leaving the possibilities open for the rare cases you're thinking about, even though I doubt this would be one of them.
"It's supposed to be hard, otherwise anybody could do it!" - selfquote "High speed never compensates for wrong direction!" - unknown
|
|
|
|
|
Thanks a lot for the suggestion Roger,
I am wondering where I should close the thread's handle (CloseHandle(hThread) ) if I do not check for its actual completion. Receiving the message handler's call does not mean the thread's already returned I think? Another problem is that my task may contain multiple thread creations at the same time, the window would need to know when they all terminated too, which then I will get their exit codes for processing(GetExitCodeThread ) as well as retrieve a timestamp at the time.
Some sort of "wait-until-all-done" is still needed for my case I think? And obviously that shouldn't be done in the main window. That's why I thought about creating a thread or a timer which creates and does my thread tasks.
Thanks again,
Best Regards,
Johnny
|
|
|
|
|
In short, here's what you should do when the thread has finished its work:
1. Post a user defined message with ::PostMessage(...) to the main thread to inform it that the worker thread is terminating.
2. In the message handler you wait on the thread handle to know when the thread has terminated.
3. [Optional] Get the exit code of the thread with ::GetExitCodeThread(...) .
4. Close the thread handle with ::CloseHandle(...) .
Read this[^] excellent article for more info about how to use worker threads.
Regarding your problem with multiple worker threads I suggest that you post the thread ID from the worker threads with the user defined message.
You should have a mapping between thread IDs and their handles. In the message handler you get the thread ID, look up the thread handle in the map and continue from #2 above. Don't forget to remove the thread ID and its handle from the map when you're done with it in the message handler.
"It's supposed to be hard, otherwise anybody could do it!" - selfquote "High speed never compensates for wrong direction!" - unknown
|
|
|
|
|
Thanks again Roger,
for very informative reply and link. They helped greatly.
Best Regards,
Johnny
|
|
|
|
|
J.B. wrote: Thanks again Roger,
for very informative reply and link. They helped greatly.
You're most welcome Johnny.
I'm pleased to hear that I was able to help you, so thanks for telling me.
"It's supposed to be hard, otherwise anybody could do it!" - selfquote "High speed never compensates for wrong direction!" - unknown
|
|
|
|
|
It sounds like you’re after the MsgWaitForMultipleObjects[^] function.
On a side note, you probably should be using _beginthreadex[^].
Here’s a quote from MSDN on the CreateThread function:
A thread in an executable that calls the C run-time library (CRT) should use the _beginthreadex and _endthreadex functions for thread management rather than CreateThread and ExitThread; this requires the use of the multi-threaded version of the CRT. If a thread created using CreateThread calls the CRT, the CRT may terminate the process in low-memory conditions.
Steve
|
|
|
|
|
Hi
How we differenciate between
1) send one New Mail
2) Reply a existing mail
in webdav method
i find some forum subject property have him "Re: " keyword in prefix
but the User may change the subject line of the reply mail.
Thanks
Arunkumar S
|
|
|
|
|
Hi
If i have received a Mail Named : X
and I reply that mail namely : Re: X
How can i find relationship between " X " and " Re: X "
in inbox and sent Items folder
which property is used to identify the relationship
Please anybody help me.
Thanks
Arunkumar S
|
|
|
|
|
Hi
We are using webdav method,
When reply a one mail, How to set the conversationIndex Property
through webdav method.
because we want track the conversation Mails History
Thanks
Arunkumar S
|
|
|
|
|
Hi,
How can i get the handle of the window which was having input focus just before my Application window got the focus?
Please help.
|
|
|
|
|
try
GetLastActivePopup
--
======
Arman
|
|
|
|
|
Look up 'SetFocus', which returns the handle to that window. Also look up WM_SETFOCUS message, the WPARAM contains that handle.
How you actually implement depends on how your code is written, which you did not give.
INTP
"Program testing can be used to show the presence of bugs, but never to show their absence."Edsger Dijkstra
|
|
|
|
|
John R. Shaw wrote: Look up 'SetFocus', which returns the handle to that window.
Unless it's in another thread's message queue (which is the case with the OP), then it will just return NULL .
"Approved Workmen Are Not Ashamed" - 2 Timothy 2:15
"Judge not by the eye but by the heart." - Native American Proverb
|
|
|
|
|
Thanks David,I did not considered that.
INTP
"Program testing can be used to show the presence of bugs, but never to show their absence."Edsger Dijkstra
|
|
|
|
|
Actually i want to create a floating Application, which can send text on selection of a particular option to the window which was having input focus before my app. Getfocus won't work as the window, of which i want the handle, doesn't belong to my app.
|
|
|
|
|
This[^] is not what you are looking for but it is a start.
Also check out WM_ACTIVATEAPP, your application receives this message when it is being activated or deactivated, along with the thread identifier.
If I was designing both applications I would be looking at using COM to handle the communications between them, by exposing an interface. In the old days I would have been looking at DDE, but that is obsolete.
I am still looking, because now I want to know the answer. But I will be limiting my time, so I may give up before I find an answer.
Good Luck!
INTP
"Program testing can be used to show the presence of bugs, but never to show their absence."Edsger Dijkstra
|
|
|
|
|
K Gupta wrote: Actually i want to create a floating Application,
Have you written that APP?
K Gupta wrote: which can send text on selection of a particular option to the window which was having input focus before my app.
Sending text means? Do you need to send key strokes? In that case, I would suggest you install a global hook via a DLL and then let it send key strokes. This may not be applicable if only you want your executable to be visible too. Can you elaborate a little more on your problem?
Nobody can give you wiser advice than yourself. - Cicero
brahmma
|
|
|
|