I would like to get the time my user instance is alive.
Therefore I added the following timer function.
But it does not work nevermind what I try:
using System;
using System.Collections.Generic;
using System.Timers;
using System.Threading;
using System.Windows;
public MainWindow() {
User myUser = new User();
System.Timers.Timer timer = new System.Timers.Timer(1000);
timer.Elapsed += new ElapsedEventHandler(OnTimerElapsed);
timer.AutoReset = true;
timer.Enabled = true;
myUser.setTimer(timer);
}
private void OnTimerElapsed(object source, ElapsedEventArgs e) {
User currentUser = (User)source;
MessageBox.Show("OnTimerElapsed: " + currentUser.Id);
}
This is my UserClass which includes the timer instance:
public class User : NotifyPropertyChanged {
private System.Timers.Timer _timer;
public void setTimer(System.Timers.Timer timer)
{
_timer = timer;
}
}
A Timer
is good for causing actions to happen after some interval, or on a periodic basis. But a Timer
does not in and of itself actually keep track of time. You need a Stopwatch
for that.
Something that might work in your example:
class User
{
private Stopwatch _alive = Stopwatch.StartNew();
public TimeSpan Alive { get { return _alive.Elapsed; } }
}
This adds a Stopwatch
to your User
object so that it knows how long it's been alive.
Then in your window code:
public MainWindow() {
User myUser = new User();
myUser.Timer = new System.Timers.Timer(1000);
myUser.Timer.Elapsed += (sender, e) => OnTimerElapsed(myUser);
myUser.Timer.AutoReset = true;
myUser.Timer.Enabled = true;
}
private void OnTimerElapsed(User currentUser) {
MessageBox.Show(string.Format("OnTimerElapsed: {0}, alive {1:0} seconds",
currentUser.Id, currentUser.Alive.TotalSeconds));
}
This does a couple of things:
- It changes the timer handler so that it captures and passes the
myUser
object reference to the actual handler method. In your example, you were trying to cast the source
parameter, but that's the Timer
object, not a User
object.
- It retrieves the
TimeSpan
value from the Alive
property, and displays the value as seconds.
Note that the User
object does not itself need to know anything about the Timer
object, at least not to accomplish the above.
Something like that should work; obviously you will make modifications according to your specific need.
You are trying to cast the object source
in the OnTimerElapsed
to a type User
It's a Timer
type.
You are causing an System.InvalidCastException
every time the Timer ticks.
It's not crashing, because it's on a worker thread.
By the way, simply setting a breakpoint on the line
User currentUser = (User)source;
would have revealed this error.
The handler method's first parameter is always the object that fired the event, in this case, it's the Timer instance, not the User
type defined by you.