The big Debate on DoEvents

  • Thread starter Thread starter Dave
  • Start date Start date
D

Dave

Ok All,

I have a program that receives information from the serial port.
Occasionally this information requires me to raise an event and update
a progressbar telling me how much of the information I have received.
My problem lies there. When i update the progressbar, I need to update
the display.... progressbar.refresh, nice and simple, however, if the
user clicks on the screen at any point whilst receiving information
from the serial port, the whole program appears to lock up.... the
screen goes white until the information has completed receiveing
information on the serial port. I therefore implemented an
Application.doevents() after updating the progressbar. This has slowed
the whole process down completely. The information I receive takes
about 1 minute to receive, however with a DoEvents call it takes twice
as long.... this is not acceptable!

Does anyone have any idea how to speed this up whilst also keeping the
form alive? I can't allow my users to see a (not responding) at the
top of the screen and I can't afford to have the time it takes to
receive anything double!

Please help!

Thanks

Dave
 
Ok All,

I have a program that receives information from the serial port.
Occasionally this information requires me to raise an event and update
a progressbar telling me how much of the information I have received.
My problem lies there. When i update the progressbar, I need to update
the display.... progressbar.refresh, nice and simple, however, if the
user clicks on the screen at any point whilst receiving information
from the serial port, the whole program appears to lock up.... the
screen goes white until the information has completed receiveing
information on the serial port. I therefore implemented an
Application.doevents() after updating the progressbar. This has slowed
the whole process down completely. The information I receive takes
about 1 minute to receive, however with a DoEvents call it takes twice
as long.... this is not acceptable!

Does anyone have any idea how to speed this up whilst also keeping the
form alive? I can't allow my users to see a (not responding) at the
top of the screen and I can't afford to have the time it takes to
receive anything double!

Please help!

Thanks

Dave

From my own experiences thus far, compared to it's use in VB6,
DoEvents() in Net does not seem to work and I pretend it doesn't even
exist.
However, the situation you are describing is a classic example of a
process that should be running in a separate thread and would be a
good place to start if you're not familiar with Threads.

Gene
 
Causing the UI thread to block by calling Thread.Sleep in the UI thread
will delay processing of the message queue. It really is better to
avoid Application.DoEvents and deal with the serial port processing in
another thread.

Brian
 
But....

Using System.threading.thread.sleep(xxx) doesnt keep the window alive
as far as i can tell...

Heres how the overall thing works. I have a c# class which deals with
sending, receiving etc. from the serial port. When the serial port
receives a certain line ie. "Hello World" an event is raised to my
vb.net program. Upon receiving this event I plot a point on a graph
and update my progress bar (also through a raiseevent) It can occur
that I receive around 10000 of these certain lines in one sitting and
therefore the c# event is fired 10000.

The problem lies in that while the system is receiving information from
the serial port, they must be able to continue doing things, (moving
windows, selecting windows etc.) I dont know how i can thread this
system when it only responds to events raised in the c# module of
serial communications. If i create a thread and tell it to raise the
event from the c# code will that then run all the code in the vb stuff
in a seperate thread?

thanks

Dave
 
Brian,
Causing the UI thread to block by calling Thread.Sleep in the UI thread
will delay processing of the message queue. It really is better to
avoid Application.DoEvents and deal with the serial port processing in
another thread.

To process the close button in a window?

If it is about more ports than I agree with you.

Cor
 
Dave said:
But....

Using System.threading.thread.sleep(xxx) doesnt keep the window alive
as far as i can tell...

That's what I'm saying. It will just block the UI thread which
prevents the message pump from dispatching queued messages. That means
forms will appear to hang.
Heres how the overall thing works. I have a c# class which deals with
sending, receiving etc. from the serial port. When the serial port
receives a certain line ie. "Hello World" an event is raised to my
vb.net program. Upon receiving this event I plot a point on a graph
and update my progress bar (also through a raiseevent) It can occur
that I receive around 10000 of these certain lines in one sitting and
therefore the c# event is fired 10000.

The problem lies in that while the system is receiving information from
the serial port, they must be able to continue doing things, (moving
windows, selecting windows etc.) I dont know how i can thread this
system when it only responds to events raised in the c# module of
serial communications. If i create a thread and tell it to raise the
event from the c# code will that then run all the code in the vb stuff
in a seperate thread?


The first thing we need to figure out is what thread that event from
the C# class is executing on. Is it the UI thread or something else.
If you have access to the C# code you can determine this by seeing if
it even uses a separate thread. If you don't have access to the code
then there are a couple of ways of testing this. I'll mention just
one. In the event handler examine the value of the Form.InvokeRequired
property. If true the method is executing on a thread other than the
UI thread. If false the method is executing on the UI thread.
 
That's correct. The WM_CLOSE message that is posted by closing a form
is not any different than the other windows messages. It will remain
in the message queue until the UI thread has finished waiting for the
Thread.Sleep function to return and subsequently dispatched other
messages which arrived first.

It's not about more ports. It's about keeping the UI thread running.

Brian
 
Hello Dave,
Since, MS does not provide a serial port component in .NET 1.1, which
serial port component did you use? Did you borrow a VB6 COM component
or did you use a third party control?

I have had simillar problems when I used a .NET serial port class()
from a third party. I switched to the VB6 COM component and things
started to get sorted out by themselves.

Hope this helps.
 
Hi,

Are you using a loop to receive data? Perhaps this is not best.

You should consider using the DataReceived event (VS2005) or the OnComm
event (such as my DesktopSerialIO dll -- free download from my web site),
and the call a Delegate proc to update the UI from that event.

There can be good reasons for using DoEvents in serial code (and loops can
be part of the receive process, in some cases) -- but, IMO, this isn't one
of them.

Dick

--
Richard Grier, MVP
Hard & Software
Author of Visual Basic Programmer's Guide to Serial Communications, Fourth
Edition,
ISBN 1-890422-28-2 (391 pages, includes CD-ROM). July 2004, Revised March
2006.
See www.hardandsoftware.net for details and contact information.
 
I've written a couple threading programs but I'm not an expert enough to
help on that front. It does seem the logical thing to do.

It might not be good form now that we can program threads but perhaps
some old fashioned programming would work too. Have you considered
using a counter and only calling doevents on every 10 or 20th time you
update the progressbar? You know, increment the counter each time the
progress bar is run and if the counter modulus 10 or 20 or whatever you
pick = 0 then doevents. Better yet make 10 or 20 into a variable and
you can adjust responsiveness vs speed on the fly.
 
Back
Top