Button click - form update?

3289 views
Skip to first unread message

Justin Rich

unread,
Sep 11, 2007, 12:39:27 PM9/11/07
to
So another simple question from me :)

as im working away ive made a button that does a series of wonderful
things.. and as it goes along it suppose to update a label to let the user
know what stage its at... but.. the rendering isnt done until after the code
is completed... how do i tell it to render so that the label gets updated?

Thanks
Justin


Nicholas Paldino [.NET/C# MVP]

unread,
Sep 11, 2007, 12:57:33 PM9/11/07
to
Justin,

The short answer, call the static DoEvents method on the Application
class in the System.Windows.Forms namespace.

The long answer has to do with how windows process messages sent to
them. When you click on your button, a windows message is sent to your
button class indicating that the button was pressed. .NET handles this
message and then transforms it into your event.

This is just one of a number of windows messages that can be sent to
your window. Many different messages are sent to tell it when it is being
moved, when it is clicked, the mouse is moving over it, etc, etc, etc.

In order to handle all of this, all the messages for the entire
application are placed in a queue, and processed sequentially.

When you set the text of a label, you are setting the bit of data
indicating what the text is, but the label still has to repaint itself. In
order to do this, the label places a message into the queue saying "hey,
repaint myself".

However, when you are processing your button press, you can't process
other windows messages. You have to wait until your code is done to get to
the point where the label can process the message to repaint itself.

Now, calling DoEvents will process all the messages that are in the
queue. In your case, your label will update, but if other messages have
been waiting (and there most likely are, like mouse movements, window
deactivations, clicks, etc, etc), then they are processed as well.

This could introduce some subtle bugs (involving synchronization) into
your program.

The better solution would be to do all of your wonderful things on
another thread, and then call the Invoke method on a control, passing a
delegate to update the UI when needed. This will cause a message to be sent
to the UI thread to update itself, but since you are handling all of the
processing on the other thread, it should update immediately (or very close
to).


--
- Nicholas Paldino [.NET/C# MVP]
- m...@spam.guard.caspershouse.com


"Justin Rich" <jric...@yahoo.spam.com> wrote in message
news:e2$%23SJJ9H...@TK2MSFTNGP03.phx.gbl...

Peter Duniho

unread,
Sep 11, 2007, 1:15:54 PM9/11/07
to
Nicholas Paldino [.NET/C# MVP] wrote:
> Justin,
>
> The short answer, call the static DoEvents method on the Application
> class in the System.Windows.Forms namespace.

IMHO, DoEvents() is the last option anyone should choose for addressing
this sort of thing, and as such it's definitely not what ought to be
proposed as the first answer, even if it happens to be short.

It's simple to implement, but BackgroundWorker and similar solutions
aren't actually all that hard, and are much more appropriate ways of
dealing with the issue. It's such a basic issue in .NET (and Windows
programming more generally), to know how to move lengthy processing out
of the main UI thread, that once a person runs into it they should just
go ahead and learn how to do it right.

Pete

Doug Semler

unread,
Sep 11, 2007, 1:41:31 PM9/11/07
to
On Sep 11, 12:57 pm, "Nicholas Paldino [.NET/C# MVP]"

Subtle? Call DoEvents in Windows message event handler that updates a
second control right before the DoEvents() call. That second control
has an event handler that updates a the first control right before a
DoEvents() call. Convince original programmer to do work in
background thread. All well. Except original programmer now accesses
the form controls from background thread. Cannot convince original
programmer that this is not good.

Ignacio Machin ( .NET/ C# MVP )

unread,
Sep 11, 2007, 1:43:57 PM9/11/07
to
Hi,

"Justin Rich" <jric...@yahoo.spam.com> wrote in message
news:e2$%23SJJ9H...@TK2MSFTNGP03.phx.gbl...

What if you do your processing (that seems to be a time consuming opertion)
in a separate thread?

Then you can use Control.Invoke to update the UI


Peter Duniho

unread,
Sep 11, 2007, 1:48:33 PM9/11/07
to
Doug Semler wrote:
> Subtle? Call DoEvents in Windows message event handler that updates a
> second control right before the DoEvents() call. That second control
> has an event handler that updates a the first control right before a
> DoEvents() call. Convince original programmer to do work in
> background thread. All well. Except original programmer now accesses
> the form controls from background thread. Cannot convince original
> programmer that this is not good.

Nicholas did specifically say for the access from the background thread
to be done via a call to Invoke(), which is a correct and perfectly
acceptable way to interact with form controls from a background thread.

Why would you want to convince anyone that "this is not good"?

I agree (obviously) that DoEvents() is not the right solution, but I
don't really understand the rest of your reply. One one decides not to
use DoEvents(), that necessarily implies moving the code to another
thread, and if the code exists in another thread it will necessarily
have to somehow interact with the form controls from that thread if
those controls are to be updated with respect to the work in the thread.

Doing that isn't a problem at all, as long as it's done correctly.

Pete

Justin Rich

unread,
Sep 11, 2007, 1:50:21 PM9/11/07
to
sounds good to me.. where do i learn?


"Peter Duniho" <NpOeS...@NnOwSlPiAnMk.com> wrote in message
news:13edjab...@corp.supernews.com...

Nicholas Paldino [.NET/C# MVP]

unread,
Sep 11, 2007, 2:01:11 PM9/11/07
to
I agree, I would never use DoEvents, but some people just want the quick
and dirty solution.


--
- Nicholas Paldino [.NET/C# MVP]
- m...@spam.guard.caspershouse.com

"Peter Duniho" <NpOeS...@NnOwSlPiAnMk.com> wrote in message
news:13edjab...@corp.supernews.com...

Justin Rich

unread,
Sep 11, 2007, 1:58:59 PM9/11/07
to
That's a great explanation. Thanks

on the topic of how things process.. is there by any chance a huge
chart/document that breaks down the order of things? basically in regards to
when you do something the order or events/methods that are run.

it seems to me (from what little I know) that when I click a button (or
whatever) there are about 50 events before my button code and another 50
after (ok, slight exaggeration)

Thanks
Justin

"Nicholas Paldino [.NET/C# MVP]" <m...@spam.guard.caspershouse.com> wrote in
message news:ug0DPRJ9...@TK2MSFTNGP02.phx.gbl...

Nicholas Paldino [.NET/C# MVP]

unread,
Sep 11, 2007, 2:20:44 PM9/11/07
to
Justin,

The documentation for any particular event is usually the best resource
for something like this. However, some deductive thought will usually be
correct. For example, with a click event, you will have something like:

MouseDown
Click
MouseUp

I've abbreviated for the sake of clarity, but generally, that's the
case.


--
- Nicholas Paldino [.NET/C# MVP]
- m...@spam.guard.caspershouse.com

"Justin Rich" <jric...@yahoo.spam.com> wrote in message

news:OSODv1J...@TK2MSFTNGP04.phx.gbl...

Doug Semler

unread,
Sep 11, 2007, 2:44:22 PM9/11/07
to

Missed a word: Accesses controls directly...Without Invoke().....and
because it has worked without Invoke() in the past it is difficult to
convince that it is wrong.

Justin Rich

unread,
Sep 11, 2007, 3:17:41 PM9/11/07
to
I havent had much luck looking that way. For instance, if im working with a
button click event, im sure i can find what events with in that object are
kicked off (like your example of the mouse down, click, up) but there are
other things that.... umm not sure what to call it... the core? kick off
that typically you dont worry about (such as the form rendering events)

these things become obvious when you see a stack trace.. didnt know if
there was some website or document that kind of gave you the generic soup to
nuts of what is kicked off for 90% of things.

really appreciate all of the information guys.

Thanks
Justin


"Nicholas Paldino [.NET/C# MVP]" <m...@spam.guard.caspershouse.com> wrote in

message news:eHMCu$J9HHA...@TK2MSFTNGP03.phx.gbl...

Peter Duniho

unread,
Sep 11, 2007, 3:40:55 PM9/11/07
to
Justin Rich wrote:
> sounds good to me.. where do i learn?

Well, MSDN and this newsgroup are decent places to start. Use Google
Groups and search this newsgroup for BackgroundWorker and/or Invoke or
read the MSDN documentation.

BackgroundWorker uses events to manage execution of code specific to
stages of background thread execution. You subscribe to the appropriate
events to do work, report progress, and receive notification of completion.

Within the DoWork event handler, you can either just use the built-in
progress reporting and let the event handler for that update the form
controls, no Invoke() required, or you can call Invoke() from the DoWork
event handler itself and update the form controls that way.

If you have questions after making an attempt to read the documentation
and existing threads and trying to implement it yourself, this newsgroup
can be a very good resource for refining the discussion to answer those
questions.

Pete

Peter Duniho

unread,
Sep 11, 2007, 3:42:30 PM9/11/07
to
Doug Semler wrote:
> Missed a word: Accesses controls directly...Without Invoke().....and
> because it has worked without Invoke() in the past it is difficult to
> convince that it is wrong.

Ah. Yes, that's a significant difference in meaning. :) And yes, I
agree it can sometimes be hard to convince someone that just because it
worked without using Invoke() before, that doesn't mean failing to use
Invoke() is correct.

Much better to indoctrinate new .NET programmers from the outset. :)

Thanks for clarifying.

Pete

Peter Duniho

unread,
Sep 11, 2007, 3:51:51 PM9/11/07
to
Justin Rich wrote:
> I havent had much luck looking that way. For instance, if im working with a
> button click event, im sure i can find what events with in that object are
> kicked off (like your example of the mouse down, click, up) but there are
> other things that.... umm not sure what to call it... the core? kick off
> that typically you dont worry about (such as the form rendering events)
>
> these things become obvious when you see a stack trace.. didnt know if
> there was some website or document that kind of gave you the generic soup to
> nuts of what is kicked off for 90% of things.

I'm not aware of any sort of comprehensive documentation along those
lines. However, typically you have no need to worry about that sort of
thing (and I'm not just saying that in a sort of "don't worry your
pretty little head about it" way...I really mean that most of the time,
no programmer ever needs to concern themselves with the events that they
don't specifically need to handle).

You mention "form rendering events", but these are done only in response
to very specific needs: either the code has explicitly "invalidated" a
region of the control or window, or the user has implicitly done so by
rearranging the windows on the screen somehow (either task switching,
click-and-drag, etc.) They are handled along with all the other
messages normally in an iterative way, and don't represent any sort of
intervening handling that has to occur as other messages are processed
as well.

If you're really curious, you can override the WndProc method in your
form class and use the Debug.WriteLine() method to print out all the
message codes that come through to the debug console. I think you'll
find that in reality there aren't actually that many messages.

If you look at the stack trace for a specific message, there can be a
fair number of functions in between your top-level message loop and the
final message handling function, but that doesn't mean a lot of work is
being done; that's just part of the normal user-input processing
mechanism, designed to allow a variety of input devices (keyboard and
mouse being primary of course) to all be funneled into a single message
handling routine.

The one thing that could lead to it looking like there are a lot of
messages is that whenever you move the mouse, you get mouse move
messages, and these can occur quite frequently. But they are only in
response to the mouse movements, and don't really represent much overhead.

If after the above, you still feel that you don't understand some
important aspect of the handling of window messages and events that are
raised as a result, perhaps you could provide a specific example of what
you're talking about. Doing so might help people offer more specific
and relevant comments.

Pete

Justin Rich

unread,
Sep 11, 2007, 3:57:23 PM9/11/07
to
Great, just needed to know where to start (BackgroundWorker)
i'll get to reading and im sure i'll be back with problems :)

really appreciated all of the detailed help!

Thanks
Justin

"Peter Duniho" <NpOeS...@NnOwSlPiAnMk.com> wrote in message

news:13edrq8...@corp.supernews.com...

Justin Rich

unread,
Sep 11, 2007, 4:32:14 PM9/11/07
to
Actually where I ran in to the problem is with a webpart that uses a web
service.
I barely got generic webparts to work correctly in WSS 3.0 and once i did, i
saw a lot of strange behavior with what im making now. Mostly things not
updating when i thought they should.. which i could only chalk up as some
misunderstanding of the order of things... since i was able to get the code
to work fine in a basic asp.net page and c# windows app... and i was able to
use the other webpart based code (meaning, ive done everything this webpart
should do, just each part on its own)

probably something i should direct more to the WSS dev newsgroup.. but i
figured there would be some value in knowing this anyways.

sort of hard to debug webparts :-/

again, thanks for all of your help.

Justin

"Peter Duniho" <NpOeS...@NnOwSlPiAnMk.com> wrote in message

news:13edsep...@corp.supernews.com...

Peter Duniho

unread,
Sep 11, 2007, 7:28:44 PM9/11/07
to
Justin Rich wrote:
> Actually where I ran in to the problem is with a webpart that uses a web
> service.
> [...]

>
> probably something i should direct more to the WSS dev newsgroup.. but i
> figured there would be some value in knowing this anyways.

A web-specific newsgroup would probably be more useful, yes. I don't
actually know all of the ways that the web components differ from
regular forms. But I know that they do, and for sure the general
updating mechanisms are likely to be quite different, given all of the
overhead involved in dynamically updating a web page (especially from
server-side code) versus doing so in a local-only forms application.

Pete

Reply all
Reply to author
Forward
0 new messages