Even And Deligate

P

Peter

I have the following code which uses Events and Deligate, I need to have a
timer in a library and update UI everytime the event fires.

but I am getting the following error in Reading method and the following
statement this.label1.Text = val.ToString();:

Cross-thread operation not valid: Control 'label1' accessed from a thread
other than the thread it was created on.

How can I fix this problem?


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using LabExampleLib;

namespace LabExample
{
public partial class Form1 : Form
{
TimerLib tl = new TimerLib();
int i = 0;

public Form1()
{
InitializeComponent();
tl.Reading += new TimerLib.Calculate(Reading);
}

void Reading(double val)
{
i++;
this.label1.Text = val.ToString();

}

private void button1_Click(object sender, EventArgs e)
{
tl.Start();
}
}
}


using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Timers;

namespace LabExampleLib
{
public class TimerLib
{
public delegate void Calculate(double val);
public event Calculate Reading;

private double i = 0;
System.Timers.Timer aTimer;

public TimerLib()
{
aTimer = new System.Timers.Timer();
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
}

private void OnTimedEvent(object source, ElapsedEventArgs e)
{
i++;
OnReading(i);
}

public void Start()
{
aTimer.Interval = 1000;
aTimer.Enabled = true;

}

protected void OnReading(double val)
{
if (Reading != null)
Reading(val);
}
}
}


Thank You

Peter
 
D

DrewCE

This, it seems, is a right of passage for beginning .Net users.

You are only allowed to update the UI from the UI thread. See the following
link and code excerpt from said link....

http://msdn.microsoft.com/en-us/library/ms171728(VS.80).aspx
// This method demonstrates a pattern for making thread-safe
// calls on a Windows Forms control.
//
// If the calling thread is different from the thread that
// created the TextBox control, this method creates a
// SetTextCallback and calls itself asynchronously using the
// Invoke method.
//
// If the calling thread is the same as the thread that created
// the TextBox control, the Text property is set directly.

private void SetText(string text)
{
// InvokeRequired required compares the thread ID of the
// calling thread to the thread ID of the creating thread.
// If these threads are different, it returns true.
if (this.textBox1.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText);
this.Invoke(d, new object[] { text });
}
else
{
this.textBox1.Text = text;
}
}
 
K

KWienhold

Section 15.4 of the article at the following link presents your alternatives
for dealing with this:http://www.codeproject.com/KB/cs/event_fundamentals..aspx

- HTH

You could replace System.Timers.Timer with System.Windows.Forms.Timer
and use the "Tick"-event instead of "Elapsed".
One of the differences between Timers.Timer and Windows.Forms.Timer is
that the former raises its events on a different thread than the one
it was created on, while the latter raises them on the same, which
makes it much more suitable to updating UIs.

hth,
Kevin Wienhold
 
P

Peter

DrewCE said:
This, it seems, is a right of passage for beginning .Net users.

You are only allowed to update the UI from the UI thread. See the
following link and code excerpt from said link....

http://msdn.microsoft.com/en-us/library/ms171728(VS.80).aspx
// This method demonstrates a pattern for making thread-safe
// calls on a Windows Forms control.
//
// If the calling thread is different from the thread that
// created the TextBox control, this method creates a
// SetTextCallback and calls itself asynchronously using the
// Invoke method.
//
// If the calling thread is the same as the thread that created
// the TextBox control, the Text property is set directly.

private void SetText(string text)
{
// InvokeRequired required compares the thread ID of the
// calling thread to the thread ID of the creating thread.
// If these threads are different, it returns true.
if (this.textBox1.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText);
this.Invoke(d, new object[] { text });
}
else
{
this.textBox1.Text = text;
}
}
Good luck said:
I have the following code which uses Events and Deligate, I need to have a
timer in a library and update UI everytime the event fires.

but I am getting the following error in Reading method and the following
statement this.label1.Text = val.ToString();:

Cross-thread operation not valid: Control 'label1' accessed from a thread
other than the thread it was created on.

How can I fix this problem?


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using LabExampleLib;

namespace LabExample
{
public partial class Form1 : Form
{
TimerLib tl = new TimerLib();
int i = 0;

public Form1()
{
InitializeComponent();
tl.Reading += new TimerLib.Calculate(Reading);
}

void Reading(double val)
{
i++;
this.label1.Text = val.ToString();

}

private void button1_Click(object sender, EventArgs e)
{
tl.Start();
}
}
}


using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Timers;

namespace LabExampleLib
{
public class TimerLib
{
public delegate void Calculate(double val);
public event Calculate Reading;

private double i = 0;
System.Timers.Timer aTimer;

public TimerLib()
{
aTimer = new System.Timers.Timer();
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
}

private void OnTimedEvent(object source, ElapsedEventArgs e)
{
i++;
OnReading(i);
}

public void Start()
{
aTimer.Interval = 1000;
aTimer.Enabled = true;

}

protected void OnReading(double val)
{
if (Reading != null)
Reading(val);
}
}
}


Thank You

Peter

Thanks the problem is solved.
 

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