break in batch testing...

G

guy

Hi,

I'm running a batch test using a C# program. This often takes several hours
to run and iterates over a bunch of parameters (say) 1000 times.

The processor is maxed out during this time.

I'd like to provide a button that cancels the batch test when it is
partially done.

I'm thinking about putting some Wait() or Pause() code in between the
iterations and then setting a flag if a Cancel button is pushed but not sure
if this would work.

What is the standard approach to implementing this sort of thing?

Thanks
 
R

Robert Jordan

Hi,
Hi,

I'm running a batch test using a C# program. This often takes several hours
to run and iterates over a bunch of parameters (say) 1000 times.

The processor is maxed out during this time.

I'd like to provide a button that cancels the batch test when it is
partially done.

I'm thinking about putting some Wait() or Pause() code in between the
iterations and then setting a flag if a Cancel button is pushed but not sure
if this would work.

What is the standard approach to implementing this sort of thing?

Disable all UI controls but the cancel button. Call
Application.DoEvents() between the iterations, say ever x
iterations.

bye
Rob
 
J

Jon Skeet [C# MVP]

Robert Jordan said:
Disable all UI controls but the cancel button. Call
Application.DoEvents() between the iterations, say ever x
iterations.

I disagree with this, apart from disabling all UI controls. It is
better to run the iterations on a separate thread and test for a flag.
Application.DoEvents() can cause nastiness like re-entrancy. To my
mind, Application.DoEvents() is basically a throw-back to VB not having
"proper" threading for a long time, and should be avoided in almost all
situations.

UIs should be kept responsive by keeping their message pump threads
idle for as much of the time as possible.
 
G

guy

Hi Jon and Robert,

Thanks for the replies. I tried using the Application.DoEvents() suggested
by Robert but not the disable UI and it works a treat.

Jon, could you elaborate on not using this.

I'm basically popping up a "progress" dialog which reports time elapsed and
% progress through the batch test etc. and there is a Cancel button on this
dialog. The main code that popped up this progress dialog checks a flag in
this class and if set stops the batch testing. This flag is set by clicking
the Cancel button. I find that if I don't inlcude the .DoEvents() call in
the check to the flag then clicking on the Cancel button does not set the
flag...

Thanks
 
R

Robert Jordan

Hi Jon,
I disagree with this, apart from disabling all UI controls. It is
better to run the iterations on a separate thread and test for a flag.
Application.DoEvents() can cause nastiness like re-entrancy. To my
mind, Application.DoEvents() is basically a throw-back to VB not having
"proper" threading for a long time, and should be avoided in almost all
situations.

UIs should be kept responsive by keeping their message pump threads
idle for as much of the time as possible.

Well, it depends on the target "audience" of the application.
I read:
I'm running a batch test using a C# program. This often takes several
hours to run and iterates over a bunch of parameters (say) 1000 times.

The main purpose of the app appears to be the batch job and not
a fancy and responsible UI. That's the reason why I recommended
Application.DoEvents().

My mistake was not to mention the threading solution at all.

Thanks
Rob
 
J

Jon Skeet [C# MVP]

guy said:
Thanks for the replies. I tried using the Application.DoEvents() suggested
by Robert but not the disable UI and it works a treat.

Jon, could you elaborate on not using this.

I'm basically popping up a "progress" dialog which reports time elapsed and
% progress through the batch test etc. and there is a Cancel button on this
dialog. The main code that popped up this progress dialog checks a flag in
this class and if set stops the batch testing. This flag is set by clicking
the Cancel button. I find that if I don't inlcude the .DoEvents() call in
the check to the flag then clicking on the Cancel button does not set the
flag...

Sure - because presumably you're doing all your processing on the UI
thread, which is a bad idea to start with.

I suggest you read my tutorial on threads:

http://www.pobox.com/~skeet/csharp/threads/
 
J

Jon Skeet [C# MVP]

Robert Jordan said:
Well, it depends on the target "audience" of the application.
I read:


The main purpose of the app appears to be the batch job and not
a fancy and responsible UI. That's the reason why I recommended
Application.DoEvents().

My mistake was not to mention the threading solution at all.

While I agree that a UI for batch processing doesn't need to be fancy,
I disagree about responsible. A UI which is written properly to start
with can easily be extended to provide more feedback etc. No guesswork
is required as to when to call DoEvents. Also, learning just one way of
"doing it right" as regards long-running tasks and UIs is better (IMO)
than learning the "quick and dirty" way and then later learning the
"proper" way (using worker threads).
 
R

Robert Jordan

Hi Jon,
While I agree that a UI for batch processing doesn't need to be fancy,
I disagree about responsible. A UI which is written properly to start
with can easily be extended to provide more feedback etc. No guesswork
is required as to when to call DoEvents. Also, learning just one way of
"doing it right" as regards long-running tasks and UIs is better (IMO)
than learning the "quick and dirty" way and then later learning the
"proper" way (using worker threads).

If one recommends threading in conjuction with UI, then it's just
a matter of time until the next question about async UI access problems
will be placed, if ever detected and recognized as such.
As you know, that kind of problem can be much subtle then DoEvents.

So what's the best approach to teach that in a newsgroup?
A full blown monologue about Control.Invoke or ignoring it
at all?

Thanks
Rob
 
J

Jon Skeet [C# MVP]

Robert Jordan said:
If one recommends threading in conjuction with UI, then it's just
a matter of time until the next question about async UI access problems
will be placed, if ever detected and recognized as such.
As you know, that kind of problem can be much subtle then DoEvents.

"More subtle" is a tough one to call - both are incredibly nasty if
they don't crop up regularly, but I find the ones due to async calling
are easier to avoid when you know about them.

(Fortunately Avalon is going to make things much simpler - if you call
something on the wrong thread, you'll get an exception immediately.)
So what's the best approach to teach that in a newsgroup?
A full blown monologue about Control.Invoke or ignoring it
at all?

Certainly don't ignore it - I point people to my article on threading,
written precisely for the purpose of not having to write the same thing
in several posts :)

http://www.pobox.com/~skeet/csharp/threads

and for Windows Forms programming in particular
http://www.pobox.com/~skeet/csharp/threads/winforms.shtml
 
G

guy

Thanks to both of you.

I've implemented a seperate thread with a control form that allows
interruption of the batch job. This has also had the side effect of allowing
me to perform multiple tests at the same time - a pleasant side effect I
wasn't expecting :)

I know about these technicologies (threading etc.) and have used them on
other OS's and with other languages but often need a nudge to use them in a
new language/environment.

Thanks.
 
G

guy

Jon,

Thanks for your help with the threading etc.

I've read through your stuff on the web but there's one type of lock that I
don't quite get but need to use.

In the main thread I wish to set a lock which the main thread itself can't
re-lock and the thread that i'm spawning will hold the lock and the main
thread will wait on that lock until the spawned thread has completed.

What is the best type of lock/mutex/semaphore to use for this.

So basically the main thread is in a loop and I want the loop to procede to
the next item once the spawned thread is complete. So I was thinking of
locking an object in the main thread and passing that to the spawned thread
which unlocks the object when it completes (or in the finally clause if
exception thrown).

What do you think of this idea?

Thanks
 
G

guy

Thanks Scott - that pointed me in the right direction.

In the end I wrote a thread management class which I'm going to attach a GUI
to in a short while. Basically it is reminiscent of the job batch handler on
the old mainframes. So I create a number of threads but only allow a certain
number to be running at one time and so the management class itself has 2
threads running: 1. That monitors the number of jobs (threads) running and
2. One that does cleanup and maintenance of the thread pool.

Now you're going to tell me that this thread management class already exists
in .NET aren't you? And that I've just reinvented the wheel... :)

I've based my thread management class on ArrayList.

Thanks
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top