using ElapsedEventHandler and Label

G

ginguene

Its supposed to be a very simple program, with a class to display the
updated current time every second (CAnalogTime) inside a Label in my
form, using ElapsedEventHandler from System.Timers;

The event is working, because the displaybox will show up every second
like requested.
Although the label (which i was able to initialize with a value), wont
update itself in this event.

Any ideas?

Thanx
--------------------------

public class CAnalogTime
{
public System.Timers.Timer myTimer;
public MainForm myForm;

public CAnalogTime( MainForm inForm)
{

myForm = inForm;
// There, the label will update normally ---->
myForm.label1.Text = "dfdstime";
myTimer = new System.Timers.Timer();
myTimer.Interval = 1000;
myTimer.Enabled = true;
myTimer.Elapsed += new ElapsedEventHandler(myForm.CheckInterval);
myTimer.Start();
}
}

public partial class MainForm
{
[STAThread]
public static void Main(string[] args)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
}
public MainForm()
{
InitializeComponent();
CAnalogTime myAnalogClock = new CAnalogTime( this);
}
public void CheckInterval(object sender,
System.Timers.ElapsedEventArgs e)
{
// But here the label wont update
this.label1.Text = DateTime.Now.ToLongTimeString();
// And strangely, the textbox will display every second :
MessageBox.Show("toto");
}
}
--------------------------
 
J

Jason Hales

The following should work BUT PLEASE READ the following paragraph:
after your this.label1.Text = DateTime.Now.ToLongTimeString(); add the
following
this.label1.Refresh();
or
Application.DoEvents();

Application DoEvents() will allow your app to yield to allow Windows to
process any pending events such as redrawing invalid parts of the
screen.

*** MULTI-THREADING ISSUES ***
One of the most important things to bear in mind with multithreading is
that you MUST ONLY communicate with control using the thread that
created, ie your main app. By using a thread from the ThreadPool,
created by using the Timer class from System.Timers class you have
created a new thread and have borken that rule.

It might be OK with a little app but can create subtle reliability
issues that are really hard to track down and replicate.

There's loads of good info around about this subject. I'd also
recommend .NET Multhreading by Alan L Dennis (ISBN 1-930110-54-5)

The quickest answer is to loook at the InvokeRequired property on
this.label1 to see if you're in a different thread and use
this.label1.Invoke if you are. Here's the code you could try:

public void CheckInterval(object sender, System.Timers.ElapsedEventArgs
e)
{
InvokeUpdateLabel();
}


private void InvokeUpdateLabel()
{
if (this.label1.InvokeRequired)
{
this.label1.Invoke(new MethodInvoker(InvokeUpdateLabel));
}
else
{
this.label1.Text = DateTime.Now.ToLongTimeString();
this.label1.Refresh();
}
}

You can see that it just reinvokes itself in the correct thread

Jason
 
M

Mattias Sjögren

Any ideas?

I suggest you use the System.Windows.Forms.Timer component instead.


Mattias
 
J

Jason Hales

I'd suggest you use the System.Windows.Forms.Timer component instead.
Good point, it will run be in the same thread so need to worry about
Invoke/InvokeRequired.

But if CheckInterval() starts to take more than a few seconds to run
(as these things have a tendency to do the more they get developed)
you'll end up blocking the main thread resulting in a slow UI and hence
slow redrawing of thr screen
 

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