[英]Timer in Windows 8.1 - how to mimic Timer(TimerCallback) constructor?
I am porting an existing .NET class library that uses System.Threading.Timer to a Windows Store app that targets Windows 8.1. 我要将使用System.Threading.Timer的现有.NET类库移植到面向Windows 8.1的Windows应用商店应用中。 The
Timer
class is available, but a few options seem to be missing in relation to the corresponding .NET Framework Timer
. Timer
类可用,但是相对于相应的.NET Framework Timer
似乎缺少一些选项。
In particular, there are only two constructors available in the Windows Store version: 特别是,Windows Store版本中只有两个构造函数可用:
public Timer(TimerCallback callback, Object state, int dueTime, int period);
public Timer(TimerCallback callback, Object state, TimeSpan dueTime, TimeSpan period);
.NET Framework contains this additional constructor: .NET Framework包含以下附加构造函数:
public Timer(TimerCallback callback);
which according to the MSDN documentation sets dueTime
and period
to Timeout.Infinite
and state
to the Timer
object itself. 根据MSDN文档,其将
dueTime
和period
为Timeout.Infinite
并将state
设置为Timer
对象本身。
Trying to replace the single argument constructor, I have "naively" tried to pass the Timer
object into one of the Windows 8.1 constructors, like this: 试图替换单个参数构造函数,我已经“天真”地尝试将
Timer
对象传递给Windows 8.1构造函数之一,如下所示:
Timer t;
t = new Timer(MyCallback, t, Timeout.Infinite, Timeout.Infinite); // WILL NOT WORK!!!
but of course this only yields the compilation error 但是当然这只会产生编译错误
Use of unassigned local variable 't'
使用未分配的局部变量“ t”
There is also no State
setter or SetState
method in the Timer
class, so the state
cannot be set after construction. Timer
类中也没有State
setter或SetState
方法,因此无法在构造后设置state
。
What can I do to fully mimic the full framework's Timer(TimerCallback)
constructor? 我应该怎么做才能完全模仿整个框架的
Timer(TimerCallback)
构造函数?
Note that these options are acceptable as long as you start the timer manually after the field/property is set, which means using Timeout.Infinite
for due time which you are. 请注意,只要您在设置字段/属性后手动启动计时器,这些选项就可以接受,这意味着您可以在适当的时间使用
Timeout.Infinite
。
Add a property to a state object: 向状态对象添加属性:
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.
}
And if one private field is not enough because you want to launch and track multiple, make a new class that wraps a timer. 如果一个私有字段还不够,因为您要启动和跟踪多个私有字段,请创建一个包装计时器的新类。 This could be an inner class:
这可能是一个内部类:
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.
}
}
You can use a closure. 您可以使用闭包。 For example:
例如:
Timer t = null;
t = new Timer(
_ =>
{
if (t != null)
{
// simply use t here, for example
var temp = t;
}
},
null,
Timeout.Infinite,
Timeout.Infinite);
Notice how I test that t != null
, just in case the timer already calls the callback before it has been assigned to the variable t
, which might happen if you were to use 0 as a value for dueTime. 请注意,我是如何测试
t != null
,以防万一计时器已在将回调分配给变量t
之前调用了该回调,如果您将0用作DueTime的值,则可能会发生这种情况。 With a value of Timeout.Infinite, that can't really happen, but I like being defensive in multithreaded scenarios. 有了Timeout.Infinite的值,这实际上不可能发生,但是我喜欢在多线程方案中采取防御措施。
In addition to t
, you can use any other variable that is in scope when the timer is created, as they will all be lifted into the closure (when used in the callback). 除了
t
,您还可以使用创建计时器时范围内的任何其他变量,因为它们都将被提升到闭包中(在回调中使用时)。
If you only want a method to replace the missing constructor, easing your porting effort, here it is: 如果您只想使用一种方法来替换缺少的构造函数,从而简化了移植工作,则这里是:
public static Timer Create(TimerCallback callback)
{
Timer t = null;
t = new Timer(_ => callback(t), null, Timeout.Infinite, Timeout.Infinite);
return t;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.