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文档,将dueTime
和period
为Timeout.Infinite
并dueTime
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; }