static timers

G

Guest

I need some insight into timers, the static modifier and instance memory
safety.
public class myClass
{
protected static int i = 0;
portected float myfloat;
protected static Timer staticTimer = new Timer();
}

public class myObject: myClass
{
public myClass()
{
staticTimer.Elapsed+=ElapsedEventHandler(this.onStaticTimerEvent);
staticTimer.Interval = 999;
staticTimer.enabled = true;
}
private void onStaticTimerEvent( ...)
{
lock(i)
{
i++;
myFLoat +=i;
}
}
}

Assume I create 100 instances of myObject. I assume there is only one
staticTimer. So how do the 100 instances interact with only one timer
instance? And do I need the lock on (i) - I would assume that since there is
only one timer, onStaticTimerEvent (specificlly i) would be thread safe from
other instances.

Is it practice to have the timer declared and instantiated within the
instance? In this case, one hundred staticTimers would exist and the lock(i)
would be needed.
 
I

Ignacio Machin \( .NET/ C# MVP \)

Hi,

FredC said:
I need some insight into timers, the static modifier and instance memory
safety.

Why are they static in the first place?


Assume I create 100 instances of myObject. I assume there is only one
staticTimer.

YES, and you will reset it each time you create a new instance
So how do the 100 instances interact with only one timer
instance? And do I need the lock on (i) - I would assume that since there
is
only one timer, onStaticTimerEvent (specificlly i) would be thread safe
from
other instances.

yes, you will eventually have a lot of waiting, everybody will be waiting
for i to unlock

Is it practice to have the timer declared and instantiated within the
instance? In this case, one hundred staticTimers would exist and the
lock(i)
would be needed.


What is what you want to do? The current solution is FAR from perfect.
 
M

Michael Nemtsev

Hello FredC,

Firstly, take into account register/unregister events are thread-safe if
its called from outside the class with the event.
If u call it within the class you must provide thread safety yourself by
calling += or -= within a lock statement.

Secondly, int is an atom statement, for most cases you shouldn't syncronize
it

F> I need some insight into timers, the static modifier and instance
F> memory
F> safety.
F> public class myClass
F> {
F> protected static int i = 0;
F> portected float myfloat;
F> protected static Timer staticTimer = new Timer();
F> }
F> public class myObject: myClass
F> {
F> public myClass()
F> {
F>
F> staticTimer.Elapsed+=ElapsedEventHandler(this.onStaticTimerEvent);
F> staticTimer.Interval = 999;
F> staticTimer.enabled = true;
F> }
F> private void onStaticTimerEvent( ...)
F> {
F> lock(i)
F> {
F> i++;
F> myFLoat +=i;
F> }
F> }
F> }
F> Assume I create 100 instances of myObject. I assume there is only one
F> staticTimer. So how do the 100 instances interact with only one timer
F> instance? And do I need the lock on (i) - I would assume that since
F> there is only one timer, onStaticTimerEvent (specificlly i) would be
F> thread safe from other instances.
F>
F> Is it practice to have the timer declared and instantiated within the
F> instance? In this case, one hundred staticTimers would exist and the
F> lock(i) would be needed.
F>
---
WBR,
Michael Nemtsev :: blog: http://spaces.msn.com/laflour

"At times one remains faithful to a cause only because its opponents do not
cease to be insipid." (c) Friedrich Nietzsch
 
N

Nicholas Paldino [.NET/C# MVP]

FredC,

See inline:
Assume I create 100 instances of myObject. I assume there is only one
staticTimer. So how do the 100 instances interact with only one timer
instance? And do I need the lock on (i) - I would assume that since there
is
only one timer, onStaticTimerEvent (specificlly i) would be thread safe
from
other instances.

The first thing that strikes me as odd is that you have a method named
myClass in your class. I think you meant myObject, and you meant to have it
be the constructor.

You would also be setting the interval for the timer every time you
create a class. Generally speaking, you should do this once, maybe in the
static constructor of the type that has a reference to the timer.

On top of that, you will probably get an exception somewhere along the
line. The reason for this is that you are boxing the int i before you pass
it to the lock. When you exit the lock, the boxed instance is different,
and you are trying to exit a block with a different object reference (one
that hasn't been locked on).

Finally, every instance of this class that you create is never going to
be garbage collected. The reason for this is that the class registers the
event handler with the static timer, which keeps the reference alive as long
as the timer is alive. Because it is static, it will shut down when the app
shuts down.

Needless to say, this is not optimal.

Hope this helps.
 
S

Stoitcho Goutsev \(100\)

FredC,

This code won't produce the result you probably expect.

Your timer variable is static, but you create the timer and assigned the
variable in the instance constructor. That means every new instance of my
class will create new timer and will assigned to the static variable thus
overriding the old reference. As long as there is no reference to the old
timer anymore it will eventually finalized and garbage collected. Upon
finalization the timer will be disabled, but until that you are going to
receive ticks from it.

If you fix the problem I just explained to you and since the event handler
is instance method each MyClass object will receive notification from the
timer. The event handler will be executed one by one from the same thread
pool thread. That means if the timer event is the only one that is modifying
this variable you are safe. Depending on the time needed to process the
event and the number of event handlers the timer might appear to be not
accurate enough.
 
N

Nicholas Paldino [.NET/C# MVP]

Where do you see that it will create a new instance of the timer every
time myObject is created? It will be created once, the first time the type
is accessed.
 
G

Guest

FredC said:
I need some insight into timers, the static modifier and instance memory
safety.
public class myClass
{
protected static int i = 0;
portected float myfloat;
protected static Timer staticTimer = new Timer();
}

public class myObject: myClass
{
public myClass()
{
staticTimer.Elapsed+=ElapsedEventHandler(this.onStaticTimerEvent);
staticTimer.Interval = 999;
staticTimer.enabled = true;
}
private void onStaticTimerEvent( ...)
{
lock(i)
{
i++;
myFLoat +=i;
}
}
}

Assume I create 100 instances of myObject. I assume there is only one
staticTimer. So how do the 100 instances interact with only one timer
instance?

Yes, there is only one Timer object. The event handlers will each be
started using a separate thread. As they all start at once, the system
might get quite sluggish when they do.

You might want to limit the number of handlers per timer, or fire the
timer more often and use a dispatcher to call the handlers on a rotating
scheme.
And do I need the lock on (i) - I would assume that since there is
only one timer, onStaticTimerEvent (specificlly i) would be thread safe from
other instances.

No, the timer starts the delegate in a new thread.

A lock on the variable i is totally worthless, though. What you actually
will be doing is copying the value of the variable and box it inside a
new object on the heap, and perform the lock on that object. As each
thread would create a new object to do the lock on, the locking has no
effect what so ever. You have to use a reference type variable for the
locking.
Is it practice to have the timer declared and instantiated within the
instance? In this case, one hundred staticTimers would exist and the lock(i)
would be needed.

If you want to use a static timer, add a proper static constructor to
the class where you initialize the timer.

A lock will be needed regardless if you have one or a hundred timers.
 
S

Stoitcho Goutsev \(100\)

Oops, I'm sorry.
Just ignore my fitst comment. I thought I saw 'new Timer()' in the instnace
constructor. I was wrong.


--

Stoitcho Goutsev (100)

Nicholas Paldino said:
Where do you see that it will create a new instance of the timer every
time myObject is created? It will be created once, the first time the
type is accessed.
 

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