我正在将一个使用System.Threading.Timer的现有.NET类库移植到面向Windows 8.1的Windows应用商店应用。 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 documentation设置dueTime
和period
设置Timeout.Infinite
和state
设置Timer
对象本身。
尝试替换单个参数构造函数,我“天真地”试图将Timer
对象传递给Windows 8.1构造函数之一,如下所示:
Timer t;
t = new Timer(MyCallback, t, Timeout.Infinite, Timeout.Infinite); // WILL NOT WORK!!!
但当然这只会产生编译错误
使用未分配的局部变量't'
State
类中也没有SetState
setter或Timer
方法,因此构建后无法设置state
。
我可以做些什么来完全模仿完整框架的Timer(TimerCallback)
构造函数?
答案 0 :(得分:1)
请注意,只要您在设置字段/属性后手动启动计时器,这些选项都是可以接受的,这意味着您可以在适当的时间内使用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.
}
}
答案 1 :(得分:1)
你可以使用一个闭包。例如:
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作为值,则可能会发生这种情况。截至日期。使用Timeout.Infinite的值,这不可能真的发生,但我喜欢在多线程场景中保持防守。
除了t
之外,您还可以在创建计时器时使用范围内的任何其他变量,因为它们都将被提升到闭包中(在回调中使用时)。
如果您只想要一个方法来替换丢失的构造函数,从而简化移植工作,那么它就是:
public static Timer Create(TimerCallback callback)
{
Timer t = null;
t = new Timer(_ => callback(t), null, Timeout.Infinite, Timeout.Infinite);
return t;
}