Windows 8.1中的计时器 – 如何模拟Timer(TimerCallback)构造函数?

我正在将一个使用System.Threading.Timer的现有.NET类库移植到面向Windows 8.1的Windowsapp store应用。 Timer类是可用的,但是相应的.NET Framework Timer似乎缺少一些选项。

特别是,Windows Store版本中只有两个构造函数可用:

 public Timer(TimerCallback callback, Object state, int dueTime, int period); public Timer(TimerCallback callback, Object state, TimeSpan dueTime, TimeSpan period); 

.NET Framework包含此附加构造函数:

 public Timer(TimerCallback callback); 

根据MSDN文档,将dueTimeperiodTimeout.InfinitedueTime Timer对象本身。

试图替换单个参数构造函数,我“天真地”试图将Timer对象传递给其中一个Windows 8.1构造函数,如下所示:

 Timer t; t = new Timer(MyCallback, t, Timeout.Infinite, Timeout.Infinite); // WILL NOT WORK!!! 

但当然这只会产生编译错误

使用未分配的局部变量’t’

Timer类中也没有State setter或SetState方法,因此在构造之后不能设置state

我能做些什么来完全模仿完整框架的Timer(TimerCallback)构造函数?

请注意,只要在设置字段/属性后手动启动计时器,这些选项是可接受的,这意味着使用Timeout.Infinite适当的时间。

状态对象

将属性添加到状态对象:

 public class MyState { public Timer { get; set; } } //create empty state MyState s = new MyState(); //create timer paused Timer t = new Timer(MyCallback, s, Timeout.Infinite, Timeout.Infinite); //update state s.Timer = t; //now safe to start timer t.Change(..) 

私人领域

 _t = new Timer(MyCallback, null, Timeout.Infinite, Timeout.Infinite); MyCallback(object state) { // now have access to the timer _t _t. } 

内部阶级的私人领域

如果一个私有字段是不够的,因为你想要启动和跟踪多个,请创建一个包装计时器的新类。 这可能是一个内部阶级:

 public class ExistingClass { public void Launch() { new TimerWrapper(this); } private sealed class TimerWrapper { private readonly ExistingClass _outer; private readonly Timer _t; public TimerWrapper(ExistingClass outer) { _outer = outer; //start timer _t = new Timer(state=>_outer.MyCallBack(this), null, Timeout.Infinite, Timeout.Infinite); } public Timer Timer { get { return _t; } } } private void MyCallBack(TimerWrapper wrapper) { wrapper.Timer. } } 

你可以使用一个闭包。 例如:

 Timer t = null; t = new Timer( _ => { if (t != null) { // simply use t here, for example var temp = t; } }, null, Timeout.Infinite, Timeout.Infinite); 

注意我是如何测试t != null ,以防定时器在分配给变量t之前已经调用了回调,如果你使用0作为dueTime的值,可能会发生这种情况。 使用Timeout.Infinite的值,这不可能真的发生,但我喜欢在multithreading场景中防守。

除了t ,您还可以在创建计时器时使用范围内的任何其他变量,因为它们都将被提升到闭包中(在回调中使用时)。

如果您只想要一个方法来替换缺少的构造函数,从而简化移植工作,那么它是:

 public static Timer Create(TimerCallback callback) { Timer t = null; t = new Timer(_ => callback(t), null, Timeout.Infinite, Timeout.Infinite); return t; }