Timer in Windows 8.1 - how to mimic Timer(TimerCallback) constructor?

*爱你&永不变心* 提交于 2019-12-07 16:15:29

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.

State Object

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(..)

Private Field

_t = new Timer(MyCallback, null, Timeout.Infinite, Timeout.Infinite);

MyCallback(object state)
{
  // now have access to the timer _t
  _t.
}

Private Field of an Inner Class

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. With a value of Timeout.Infinite, that can't really happen, but I like being defensive in multithreaded scenarios.

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).

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;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!