Board index » cppbuilder » What's Best way to Provide a 'Cancel' job button in BDS....

What's Best way to Provide a 'Cancel' job button in BDS....


2007-05-27 02:31:18 AM
cppbuilder80
I have a long running job that reports intermediate real time results in the
window caption...sometimes we want to cancel it midstream...a Cancel Button
doesn't seem to be live while its running...I'm sure this is easy, but I'm
clueless on the protocol.......thanks.
 
 

Re:What's Best way to Provide a 'Cancel' job button in BDS....

A good idea is to investigate in multithreading.
If an event function is running, then no input is accepted.
"ActuaryOne" < XXXX@XXXXX.COM >wrote in message
Quote
I have a long running job that reports intermediate real time results in
the window caption...sometimes we want to cancel it midstream...a Cancel
Button doesn't seem to be live while its running...I'm sure this is easy,
but I'm clueless on the protocol.......thanks.
 

Re:What's Best way to Provide a 'Cancel' job button in BDS....

"ActuaryOne" < XXXX@XXXXX.COM >wrote in message
Quote
I have a long running job that reports intermediate real time results in
the window caption...sometimes we want to cancel it midstream...a Cancel
Button doesn't seem to be live while its running...I'm sure this is easy,
but I'm clueless on the protocol.......thanks.
Button presses are handled by the application's main message loop which
always executes in the application's main thread. If your task also runs in
the main thread, then mouse clicks, button presses, screen updates, etc.
will not be handled until after the task finishes. This is why the button
does not appear to be "live" while your task is running.
To allow for the cancellation of a task, your task must execute in a
separate thread so that the mouse clicks and button presses can still be
handled in the main thread. Once your task is running in a thread, it
should periodically check to see if there has been a request to cancel it (a
simple flag will do), and if so, abort the task and exit the thread.
Pressing the cancel button simply sets the cancel flag.
In VCL, screen updates must occur in the main thread (not doing so can
result in odd behavior or crashes), so if you need to invoke screen updates
from within the thread, and you are using the TThread class in the VCL, you
must perform your screen updates in a routine that is called via the
TThread::Synchronize method (which forces the code to execute within the
context of the main thread). If you do not use TThread, or if real-time
updates are not critical to your app, then you can use PostMessage to tell
the main thread to perform screen updates whenever it gets a chance.
- Dennis
 

{smallsort}

Re:What's Best way to Provide a 'Cancel' job button in BDS....

"Dennis Jones" < XXXX@XXXXX.COM >wrote:
Quote

[...] To allow for the cancellation of a task, your task
must execute in a separate thread so that the mouse clicks
and button presses can still be handled in the main thread.
The task need not be run in a seperate thread (although that
is most likely how I would approach it). For example:
for( int x = 0; x < SomeLimit; ++x )
{
if( ! (x % 100) )
{
Application->ProcessMessages();
if( SomeFlagSet )
{
// abort the process
}
}
}
~ JD
 

Re:What's Best way to Provide a 'Cancel' job button in BDS....

"JD" < XXXX@XXXXX.COM >wrote in message
Quote

"Dennis Jones" < XXXX@XXXXX.COM >wrote:
>
>[...] To allow for the cancellation of a task, your task
>must execute in a separate thread so that the mouse clicks
>and button presses can still be handled in the main thread.

The task need not be run in a seperate thread (although that
is most likely how I would approach it). For example:

for( int x = 0; x < SomeLimit; ++x )
{
if( ! (x % 100) )
{
Application->ProcessMessages();
if( SomeFlagSet )
{
// abort the process
}
}
}
Yes, this is true -- it is a much simpler approach that may be suitable for
many situations. However, it does have the disadvantage that, depending on
the amount of processing that occurs inside the loop and the values of 'x'
and the divisor (100 in your example), the program could still appear to be
unresponsive for some period of time. Even if only for a moment, that might
be enough to make it undesirable.
- Dennis
 

Re:What's Best way to Provide a 'Cancel' job button in BDS....

"Dennis Jones" < XXXX@XXXXX.COM >wrote in message
Quote

"JD" < XXXX@XXXXX.COM >wrote in message
news:46597073$ XXXX@XXXXX.COM ...
>
>"Dennis Jones" < XXXX@XXXXX.COM >wrote:
>>
>>[...] To allow for the cancellation of a task, your task
>>must execute in a separate thread so that the mouse clicks
>>and button presses can still be handled in the main thread.
>
>The task need not be run in a seperate thread (although that
>is most likely how I would approach it). For example:
>
>for( int x = 0; x < SomeLimit; ++x )
>{
>if( ! (x % 100) )
>{
>Application->ProcessMessages();
>if( SomeFlagSet )
>{
>// abort the process
>}
>}
>}

Yes, this is true -- it is a much simpler approach that may be suitable
for many situations. However, it does have the disadvantage that,
depending on the amount of processing that occurs inside the loop and the
values of 'x' and the divisor (100 in your example), the program could
still appear to be unresponsive for some period of time. Even if only for
a moment, that might be enough to make it undesirable.
Yes. But you should have a simple elapsed timer class in your
toolkit already so using that should be fine.
IMO threads are one of the most difficult
things to get right. I'd go for the simpler approach wherever
possible.
 

Re:What's Best way to Provide a 'Cancel' job button in BDS....

"Duane Hebert" < XXXX@XXXXX.COM >wrote in message
Quote

Yes. But you should have a simple elapsed timer class in your
toolkit already so using that should be fine.
Interesting idea.
Quote
IMO threads are one of the most difficult
things to get right.
That's true too. But if you use them often enough, you can get pretty good
at it!
- Dennis
 

Re:What's Best way to Provide a 'Cancel' job button in BDS....

"Duane Hebert" < XXXX@XXXXX.COM >wrote:
Quote

>[...] that might be enough to make it undesirable.

Yes. But you should have a simple elapsed timer class [...]
I get the concept but since Windows is an event driven OS,
wouldn't that tool also be event driven? If everything is
executing within the context of the same thread as you
suggest, how would the time-out be detected without calling
ProcessMessages()?
Wouldn't that require a worker thread?
Quote
IMO threads are one of the most difficult things to get
right.
I agree and I disagree.
It's not as much as getting the worker thread to do the job as
it is to get the worker thread to work with the main thread or
other worker threads. From my perspective, once one understands
race conditions and dead-locks, worker threads are a breeze to
design and impliment.
In this case, it seems that a worker thread is well advised
and I say that because every time one calls ProcessMessages,
one must also code to account for reenterence by disabling
controls and/or setting flags that certain events must check
(not to mention the overhead of calling ProcessMessages).
Quote
I'd go for the simpler approach wherever possible.
Only a fool would not but what is 'simpler'?
~ JD
 

Re:What's Best way to Provide a 'Cancel' job button in BDS....

"JD" < XXXX@XXXXX.COM >wrote in message
Quote

"Duane Hebert" < XXXX@XXXXX.COM >wrote:
>
>>[...] that might be enough to make it undesirable.
>
>Yes. But you should have a simple elapsed timer class [...]

I get the concept but since Windows is an event driven OS,
wouldn't that tool also be event driven? If everything is
executing within the context of the same thread as you
suggest, how would the time-out be detected without calling
ProcessMessages()?
Same as you suggested except that instead of just calling
ProcessMessages() based on loop count, check for elapsed
time>something sensible and then call ProcessMessages().
Quote

Wouldn't that require a worker thread?
It would require a function to get the elapsed time
since last call.
 

Re:What's Best way to Provide a 'Cancel' job button in BDS....

"Duane Hebert" < XXXX@XXXXX.COM >wrote:
Quote

[...] check for elapsed time>something sensible and then
call ProcessMessages().
<slaps head>
Ok.
~ JD