DoEvents() "Hangs"

  • Thread starter Thread starter cedmunds
  • Start date Start date
C

cedmunds

Group:

We have an application that is calling a stored proc. The stored proc
takes anywhere from 15 to 90 minutes to run.

In order to keep the GUI responsive, we are using a BackgroundWorker to
actually make the call to the stored proc. The app then sits in a loop
that awakes every second and updates an elapsed time value.

The problem that we are having is that after a certain period of time -
which is rarely the same amount - the call to DoEvents hangs (does not
return).

I was hoping the group could help us with: a) why thiat might be
occuring and b) what if anything can be done to fix it.

Here's the key areas of the code:

This is from the method that starts the ball rolling:
 
Hello (e-mail address removed),

Do people really still use DoEvents() (is it even valid in C#?). You should
be using Thread.Join or Thread.Sleep (or a synchronization semantic like
a Mutex or Monitor).


Thanks,
Shawn Wildermuth
Speaker, Author and C# MVP
http://adoguy.com
 
Why are you having the front end stop if you are running the operation on a
background thread anyways?

Couldn't you just make the background thread tell the front end when it is
done through a callback/event/etc

Cheers,

Greg Young
MVP - C#
http://codebetter.com/blogs/gregyoung
 
The business requirements are such that the call needs to be
synchronous but the GUI needs to be semi-responsive while it is
running.

The users are not able to perform any other taks in the app while the
call is being processed but when the process is long running they
don't want the screen to "white" out either.

That is the only reason for the threading.
 
Exactly, I am using the BackgroundWorker (see code snippets) above. In
essence, I am firing off the stored proc and then putting the GUI in a
loop that sleeps for a while, awakens, and updates itself and then goes
back to sleep. This continues until the stored proc returns.

But the trouble is that it (the SleepAndUpdate loop) stops working
after a while. When it first fires up, everything is great and then
after an indeterminate period of time the DoEvents() stops returning.

It is puzzling.

I hate to take the "easy" way out and point to the framework but that
is indeed what it seems like the trouble is.

All helpful thoughts and suggestions (not the snarky ones about "Do
people really still use DoEvents() (is it even valid in C#?).") are
appreciated.
 
Don't sleep on the UI thread. Ever. You're preventing the UI
thread from processing any messages for 1 second. Disable the main form
and its controls or launch another simple modal form to actually launch
the processing thread and display some sort of "I'm running" indicator
until it receives notification (not by polling, by callback) that the
thread has finished.
Your implementation is broken, not the framework. This is not meant
to be snarky, just straightforward.
 
wfa:

Sorry, I wasn't indicting you. I just get frustrated with condescending
posts.

In any case, the issue is that when the call returns then we must move
onto the next step in the process. We let the stored proc run in the
back ground BUT we can't continue on with processing until the stored
proc returns. That is why we go into a sleep loop. Otherwise, we just
loop until the semaphore is reset.
 
I agree with this completely.

You can just leave the UI doing nothing and wait on an event from the worker
thread (i.e. with a modal dialog). This is a quite common task (and many
people include "cancel" buttons on such a screen so the user can stop what
they are doing).

Personally I would also question the business requirement of having a user
on the system unable to use their interface for 15-90 minutes as this sounds
exactly like the type of job that should be done by some system service. By
putting the requirement that the person can't do anything when this is
happenning also leads directly to the conclusion that noone can be doing
anything while this happens on the database (or atleast touching the same
data).

Cheers,

Greg
 
Have the background thread notify the foreground thread when it is complete
.....

Also you can't continue with the process involving the sproc but can you do
other things while waiting or is the app designed to only do this one
process and the one process doesn't make sense to be doing multiples (i.e.
running a big report).

Cheers,

Greg
 
Yes, well, while I won't defend the architecture, we are constrained to
work within it.

I did try removing the Sleep from the wait loop. Oddly enough, this
caused the DoEvents to hang sooner. This led us to make the sleep
longer which seems to make the situation better though the hanging
still occurs - just much later in the process.

Using a Modal dialog box is a solution but we are still faced with the
GUI not responding to simple redraw messages.

We believe that will the current solution is ugly it should still work.
We remain puzzled that the DoEvents will work but then suddenly stop
responding.
 
Note that I said to use a modal dialog and an event/call back.

You would start the thread .... then just sit and do nothing (just show your
screen maybe with a cancel button). There is no loop (well there is but its
not in your code). Later your thread will raise the event or directly call
you back at which point you continue your processing.

Cheers,

Greg
 
Well you are constrained to the architecture but it is up to you as the
engineers to build a solid implementation. We are not trying to offend
you (or whoever designed this originally and now seems married to it)
but we're trying to get the point across that your current design is
broken. Get rid of DoEvents and get rid of Sleep, you don't need either
one of them. It will only work if you're lucky, the solutions we're
pushing will work reliably. Don't sit there puzzling over it for
another minute. Take 30 minutes and rewrite it correctly.
 
Hi,
We believe that will the current solution is ugly it should still work.
We remain puzzled that the DoEvents will work but then suddenly stop
responding.

Well I hope you take some of the very good advice you have been given so
far, but I must admit I do agree with your statement here. Hangs like this
can be caused by deadlocks though you haven't shown enough code to tell us
much there. I also wonder if your thread code might be poking its nose into
UI components in a non thread safe way?

Cheers
Doug Forster
 
Doug said:
Hi,


Well I hope you take some of the very good advice you have been given
so far, but I must admit I do agree with your statement here. Hangs
like this can be caused by deadlocks though you haven't shown enough
code to tell us much there. I also wonder if your thread code might
be poking its nose into UI components in a non thread safe way?

....which is to say, in any way at all.

My first thought on reading the initial post in this thread was that the
background thread is trying to update the UI without going through
Control.{Begin}Invoke - that's a sure recipe for UI hangs like this. But
since he's apparaently using .NET 2.0, I doubt that's the case, since the
2.0 Winforms classes will throw an exception if you touch them from the
wrong thread.

I agree completely with the other advice in this thread: get rid of the
sleep/doEvents loop and put up a modal form, or just disable the main form
until a callback (or event) from the worker thread indicates that it's time
to move on to the next step.

-cd
 
All helpful thoughts and suggestions (not the snarky ones about "Do
people really still use DoEvents() (is it even valid in C#?).") are
appreciated.

That may have been snarky but it was absolutely correct.
Do not use DoEvents, ever! There is never a good reason to have the
operating system perform unpredictable reentrant calls on the current
GUI thread -- because that's exactly what DoEvents does.
 
Back
Top