![](/img/trans.png)
[英]System.Threading.Timer TimerCallback delegate with parameters?
[英]Timer in Windows 8.1 - how to mimic Timer(TimerCallback) constructor?
我要將使用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文檔,其將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”
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的值,這實際上不可能發生,但是我喜歡在多線程方案中采取防御措施。
除了t
,您還可以使用創建計時器時范圍內的任何其他變量,因為它們都將被提升到閉包中(在回調中使用時)。
如果您只想使用一種方法來替換缺少的構造函數,從而簡化了移植工作,則這里是:
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.