Events and GUI question:

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

Hi,

I'm trying to update my GUI when an event is raised in my one of my
dlls.

my example code is:
-------------------
In GUI:
someLable.Text = " ";
---
---
someObj.UpdateEvent += new UpdateEventDelegate(UpdateGui);
someObj.UpdateCompleted += new UpdateCompletedDelegate(UpdateCompl);
---
---
UpdateGui()
{
someLable.Text = "Updated";
}
UpdateCompl()
{
someLable.Text = "Completed";
}
----------------------------------

In my dll:
i = 0;
while( i < 5 )
{
...
...
j = 0;
while( j < 2 )
{
....
....
j ++;
}
UpdateEvent();
i ++;
}
UpdateCompleted();
------------------------

Even though UpdatedEvent() is being raised, the changes are not
being reflected in the GUI. I mean, the changes made by the
UpdateEvent handler are not being reflected in the GUI.
But, GUI is reflecting the changes made by
UpdateCompleted event handler.

I can't understand why. What could be the problem.

Kindly let me know,

Cheers,

Naveen.
 
If you are calling your DLL directly from the GUI, then you have only
one thread, the UI thread, doing all of the work.

Since a single thread can do only one thing at a time, your
UpdateEvent() is being raised, and the event handler is being called,
but simply setting someLabel.Text to something doesn't cause the GUI to
be redrawn immediately.

In fact, what happens is that the someLabel.Text = "Updated"; line
changes a property of the label (its text), and then sets the label as
"stale" in the GUI, so that the next time the UI thread gets around to
looking to see what needs repainting, it will find the "stale" label
and redraw it.

However, since the UI thread is busy inside your DLL doing processing
work, it doesn't get back to its redrawing the GUI until later... in
fact, not until after it finishes what it's doing in your DLL and
returns to your main form and then out... back to what's call the
"event loop". Only then does it notice that the label is stale and
needs to be redrawn.

One alternative is to call Application.DoEvents() after you set the
label text. You can read about Application.DoEvents() here:

http://msdn.microsoft.com/library/d...windowsformsapplicationclassdoeventstopic.asp

However, this can have unforseen consequences: you can't tell
DoEvents() what GUI events to handle. It does them all before returning
to you. So, if your use has clicked another button while you're doing
your processing work, the UI thread will call the event handler for
that button, even while you're "in the middle of" your update, so you
can end up doing tasks within tasks. Could get ugly.

The other choice (the one recommended by Microsoft) is to use a
background thread for your processing work, leaving the UI thread free
to repaint the screen. You can still raise events and change the screen
from the background thread... you just need to use Invoke, because a
background thread can't mess with controls on the screen.

However, having worked in multi-threaded environments before, I can
tell you that you really don't want to get into background threads
unless you have plenty of time to experiment and learn. Although it is
the "right solution," it's even more complicated than calling
DoEvents().

Anyway, that's the long-winded answer: why doesn't the UI thread
repaint your label while you're doing your update? Because it's busy
doing the update.
 
Hi Bruce,

Thank you very much for taking time to explaining.
It is very specific and good explanation, much appriciated.

I tried Application.DoEvents(), it worked.

Thanks once again.

Cheers,

Naveen.
 
However, having worked in multi-threaded environments before, I can
tell you that you really don't want to get into background threads
unless you have plenty of time to experiment and learn. Although it is
the "right solution," it's even more complicated than calling
DoEvents().

It's certainly more complicated than calling DoEvents if DoEvents is
going to work - however, I think that judging when DoEvents is going to
work involves learning nearly as much as learning how to do it
properly. Threading is one of those things that most people are going
to need to learn how to do properly at some stage or other - I think
it's worth avoiding the "band-aid" of DoEvents (which can cause really
hard to diagnose bugs - re-entrancy is harder to spot than deadlocks,
IMO) in the first place. Just MHO, obviously.

To the OP - if you want to know more about multi-threading, see
http://www.pobox.com/~skeet/csharp/threads
 
Back
Top