簡體   English   中英

Windows 8.1中的Timer-如何模仿Timer(TimerCallback)構造函數?

[英]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文檔,其dueTimeperiodTimeout.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM