Controlled non UI timer in metro app (.NET)

.net, timer, windows-8, windows-runtime, winrt-xaml

Solution

Since the UI should be very responsive in Metro apps - it might be enough to run a DispatcherTimer and call Task.Run() on things you want run on background thread.

If that does not work for you - see if this does. It should have a similar API to the DispatcherTimer, but run on a different thread. Not that it keeps waiting for exactly the duration of the Interval set, so the timer will be notoriously late. It is also not exactly thread safe and I only played with it for 10 minutes, so it might not always work, but since it is open source - you can modify it to fit your bill.

public class BackgroundTimer
{
    private AutoResetEvent _stopRequestEvent;
    private AutoResetEvent _stoppedEvent;

    #region Interval
    private TimeSpan _interval;
    public TimeSpan Interval
    {
        get
        {
            return _interval;
        }
        set
        {
            if (IsEnabled)
            {
                Stop();
                _interval = value;
                Start();
            }
            else
            {
                _interval = value;
            }
        }
    }
    #endregion

    public event EventHandler<object> Tick;

    #region IsEnabled
    private bool _isEnabled;
    public bool IsEnabled
    {
        get
        {
            return _isEnabled;
        }
        set
        {
            if (_isEnabled == value)
                return;

            if (value)
                Start();
            else
                Stop();
        }
    } 
    #endregion

    public BackgroundTimer()
    {
        _stopRequestEvent = new AutoResetEvent(false);
        _stoppedEvent = new AutoResetEvent(false);
    }

    public void Start()
    {
        if (_isEnabled)
        {
            return;
        }

        _isEnabled = true;
        _stopRequestEvent.Reset();
        Task.Run((Action)Run);
    }

    public void Stop()
    {
        if (!_isEnabled)
        {
            return;
        }

        _isEnabled = false;
        _stopRequestEvent.Set();
        _stoppedEvent.WaitOne();
    }

    private void Run()
    {
        while (_isEnabled)
        {
            _stopRequestEvent.WaitOne(_interval);

            if (_isEnabled &&
                Tick != null)
            {
                Tick(this, null);
            }
        }

        _stoppedEvent.Set();
    }
}

Problem

I need a timer class which should provide functionality to start/stop/enable/disable and should be NON UI. I see 2 options DispatcherTimer -> has all functionality except that it is executed on UI thread ThreadPoolTimer -> No control over periodic timer. I was thinking of creating wrapper over threadpool timer, but seems very complex as no/limited control over it. How to design a timer class for the stated sceneario. (I require something similar to System.Threading.Timer).

Original source