定时器在C#中的单独类中不起作用

时间:2015-03-07 17:14:48

标签: c# wpf timer

我想得到我的用户实例活着的时间 因此我添加了以下计时器功能 但它无法解决我的尝试:

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

这是我的UserClass,其中包含计时器实例:

public class User : NotifyPropertyChanged {

    private System.Timers.Timer _timer;

    public void setTimer(System.Timers.Timer timer)
    {
        _timer = timer;
    }
}

2 个答案:

答案 0 :(得分:2)

Timer适用于在某个间隔后或定期执行操作。但Timer本身并不能实际记录时间。你需要Stopwatch

在你的例子中可能有用的东西:

class User
{
    private Stopwatch _alive = Stopwatch.StartNew();

    public TimeSpan Alive { get { return _alive.Elapsed; } }
}

这会在您的Stopwatch对象中添加User,以便它知道它活了多久。

然后在你的窗口代码中:

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

这有两件事:

  • 它更改了计时器处理程序,以便捕获并将myUser对象引用传递给实际的处理程序方法。在您的示例中,您试图转换source参数,但这是Timer对象,而不是User对象。
  • 它从TimeSpan属性中检索Alive值,并将值显示为秒。

请注意,User对象本身不需要了解Timer对象,至少不能完成上述任务。

这样的事应该奏效;显然你会根据你的具体需要进行修改。

答案 1 :(得分:0)

您正尝试将object source中的OnTimerElapsed转换为类型User

它是Timer类型。

每次定时器滴答时,您都会导致System.InvalidCastException。 它没有崩溃,因为它在工作线程上。

顺便说一句,只需在行

上设置断点即可

User currentUser = (User)source;

会发现此错误。

处理程序方法的第一个参数始终是触发事件的对象,在这种情况下,它是Timer实例,而不是您定义的User类型。