Timer is not working in separate class in C#

Deadly 提交于 2020-02-24 11:23:05

问题


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;
    }
}

回答1:


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.




回答2:


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.



来源:https://stackoverflow.com/questions/28917628/timer-is-not-working-in-separate-class-in-c-sharp

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!