我需要一个计时器类,它应该提供启动/停止/启用/禁用的功能,并且应该是非 UI。
我看到 2 个选项
我正在考虑在线程池计时器上创建包装器,但似乎非常复杂,因为没有/有限控制它。
如何为所述场景设计计时器类。 (我需要类似于 System.Threading.Timer 的东西)。
最佳答案
由于 UI 在 Metro 应用程序中应该非常敏感 - 运行 DispatcherTimer 并在您想要在后台线程上运行的事情上调用 Task.Run() 可能就足够了。
如果这对您不起作用 - 看看这是否有效。它应该具有与 DispatcherTimer 类似的 API,但在不同的线程上运行。并不是说它一直在等待 Interval 集的持续时间,因此计时器将众所周知地迟到。它也不完全是线程安全的,我只玩了 10 分钟,所以它可能并不总是有效,但由于它是开源的 - 您可以修改它以适应您的需求。
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();
}
}
关于.net - Metro 应用程序 (.NET) 中的受控非 UI 计时器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10493253/