Run time error when subscribing to an event

T

Tony Johansson

Hello!

Below I have two easy classes that are relevant for my question. These are
called Clock and Ticker.
In class Clock I subscribe to the event tick which is of type Tick that
exist in the Ticker class in this way
pulsed.tick += new Ticker.Tick(RefreshTime);
When I use this construction of subscribing to the event I get a run time
error that say the following
"Cross-thread operation not valid: Control 'digital' accessed from a thread
other than the thread it was created on."
I have read in different books that you can subscribe to event by using
these two statement which I call statement 1 and 2 below
Statement 1 : pulsed.tick += new Ticker.Tick(RefreshTime); // This gives run
time error
Statement 2 : pulsed.tick += RefreshTime; //
this works fine

If I use the second statement "pulsed.tick += RefreshTime; " to subscribe to
the event it works fine.

So my question is can somebody explain to me why I can't subscribe to the
event by using
statement 1 "pulsed.tick += new Ticker.Tick(RefreshTime);"
when this statement 1 "pulsed.tick += new Ticker.Tick(RefreshTime);"
should be the same as statement 2 "pulsed.tick += RefreshTime;"


class Clock
{
private Ticker pulsed = new Ticker();
private TextBox display;

public void Start()
{
//pulsed.tick += RefreshTime;
pulsed.tick += new Ticker.Tick(RefreshTime);
}

public void Stop()
{
pulsed.tick -= new Ticker.Tick(RefreshTime);
//pulsed.tick -= RefreshTime;
}

private void RefreshTime(int hh, int mm, int ss)
{
display.Text = string.Format("{0:D2}:{1:D2}:{2:D2}", hh, mm, ss);
}
}

class Ticker
{
public delegate void Tick(int hh, int mm, int ss);
public event Tick tick;
private Timer ticking = new Timer();

public Ticker()
{
ticking.Elapsed += new ElapsedEventHandler(OnTimedElapsed);
ticking.Interval = 1000;
ticking.Enabled = true;
}

private void Notify(int hours, int minutes, int seconds)
{
if (tick != null)
tick(hours, minutes, seconds); //call delegate
}

private void OnTimedElapsed(object source, ElapsedEventArgs args)
{
int hh = args.SignalTime.Hour;
int mm = args.SignalTime.Minute;
int ss = args.SignalTime.Second;
Notify(hh, mm, ss); // call notify
}
}

//Tony
 
S

Sergey Zyuzin

Hello!

Below I have two easy classes that are relevant for my question. These are
called Clock and Ticker.
In class Clock I subscribe to the event tick which is of type Tick that
exist in the Ticker class in this way
pulsed.tick += new Ticker.Tick(RefreshTime);
When I use this construction of subscribing to the event I get a run time
error that say the following
"Cross-thread operation not valid: Control 'digital' accessed from a thread
other than the thread it was created on."
I have read in different books that you can subscribe to event by using
these two statement which I call statement 1 and 2 below
Statement 1 : pulsed.tick += new Ticker.Tick(RefreshTime); // This givesrun
time error
Statement 2 : pulsed.tick += RefreshTime; š š š š š š š š š š š š š š //
this works fine

If I use the second statement "pulsed.tick += RefreshTime; " to subscribe to
the event it works fine.

So my question is can somebody explain to me why I can't subscribe to the
event by using
statement 1 "pulsed.tick += new Ticker.Tick(RefreshTime);"
when this statement 1 "pulsed.tick += new Ticker.Tick(RefreshTime);"
should be the same as statement 2 š"pulsed.tick += RefreshTime;"

class Clock
{
š š šprivate Ticker špulsed = new Ticker();
š š šprivate TextBox display;

š š š public void Start()
š š š{
š š š š š š //pulsed.tick += RefreshTime;
š š š š š š pulsed.tick += new Ticker.Tick(RefreshTime);
š š š š }

š š špublic void Stop()
š š š{
š š š š š š pulsed.tick -= new Ticker.Tick(RefreshTime);
š š š š š š //pulsed.tick -= RefreshTime;
š š }

š š šprivate void RefreshTime(int hh, int mm, int ss)
š š š{
š š š š š display.Text = string.Format("{0:D2}:{1:D2}:{2:D2}",hh, mm, ss);
š š š}

}

class Ticker
{
š špublic delegate void Tick(int hh, int mm, int ss);
š špublic event Tick tick;
š šprivate Timer ticking = new Timer();

š špublic Ticker()
š š{
š š š šticking.Elapsed += new ElapsedEventHandler(OnTimedElapsed);
š š š šticking.Interval = 1000;
š š š šticking.Enabled š= true;
š š}

š šprivate void Notify(int hours, int minutes, int seconds)
š š{
š š š š if (tick != null)
š š š š š štick(hours, minutes, seconds); //call delegate
š š}

š šprivate void OnTimedElapsed(object source, ElapsedEventArgs args)
š š{
š š š š šint hh = args.SignalTime.Hour;
š š š š šint mm = args.SignalTime.Minute;
š š š š šint ss = args.SignalTime.Second;
š š š š šNotify(hh, mm, ss); // call notify
š š}

}

//Tony

Hi, Tony

I have VS 2005. I ran your code and I'm getting the exception in both
cases.
Moreover I double checked that both subscription ways compile to the
same IL code.
So I have no easy explanation :(

Thanks,
Sergey
 

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