计时器在 C# 中单独工作 class
Timer is not working in separate class in C#
我想获取我的用户实例处于活动状态的时间。
因此,我添加了以下定时器功能。
但无论我尝试什么,它都不起作用:
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;
}
}
A Timer
适用于在一段时间后或定期发生动作。但是 Timer
本身并不能真正跟踪时间。为此你需要 Stopwatch
。
可能适用于您的示例的内容:
class User
{
private Stopwatch _alive = Stopwatch.StartNew();
public TimeSpan Alive { get { return _alive.Elapsed; } }
}
这会向您的 User
对象添加一个 Stopwatch
,以便它知道它已经存活了多长时间。
然后在您的 window 代码中:
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
对象。
- 它从
Alive
属性 中检索 TimeSpan
值,并将该值显示为秒。
请注意,User
对象本身不需要知道有关 Timer
对象的任何信息,至少不需要完成上述操作。
类似的东西应该有用;显然你会根据你的具体需要进行修改。
您正在尝试将 OnTimerElapsed
中的 object source
转换为类型 User
是Timer
类型。
每次计时器滴答时,您都会导致 System.InvalidCastException
。
它没有崩溃,因为它在工作线程上。
顺便简单的在行上设置断点
User currentUser = (User)source;
会发现这个错误。
处理程序方法的第一个参数始终是触发事件的对象,在本例中,它是 Timer 实例,而不是您定义的 User
类型。
我想获取我的用户实例处于活动状态的时间。
因此,我添加了以下定时器功能。
但无论我尝试什么,它都不起作用:
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;
}
}
A Timer
适用于在一段时间后或定期发生动作。但是 Timer
本身并不能真正跟踪时间。为此你需要 Stopwatch
。
可能适用于您的示例的内容:
class User
{
private Stopwatch _alive = Stopwatch.StartNew();
public TimeSpan Alive { get { return _alive.Elapsed; } }
}
这会向您的 User
对象添加一个 Stopwatch
,以便它知道它已经存活了多长时间。
然后在您的 window 代码中:
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
对象。 - 它从
Alive
属性 中检索TimeSpan
值,并将该值显示为秒。
请注意,User
对象本身不需要知道有关 Timer
对象的任何信息,至少不需要完成上述操作。
类似的东西应该有用;显然你会根据你的具体需要进行修改。
您正在尝试将 OnTimerElapsed
中的 object source
转换为类型 User
是Timer
类型。
每次计时器滴答时,您都会导致 System.InvalidCastException
。
它没有崩溃,因为它在工作线程上。
顺便简单的在行上设置断点
User currentUser = (User)source;
会发现这个错误。
处理程序方法的第一个参数始终是触发事件的对象,在本例中,它是 Timer 实例,而不是您定义的 User
类型。