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