我需要一個定時器類,它應該提供啓動/停止/啓用/禁用的功能,並且應該不是用戶界面。城域應用程序中受控制的非UI定時器(.NET)
我看到2個選項
DispatcherTimer - >有不同之處在於它是在UI線程上執行
ThreadPoolTimer所有功能 - >沒有超過週期定時器控制。
我想通過線程池計時器創建包裝,但似乎非常複雜,因爲沒有/有限的控制權。
如何爲所述場景設計一個計時器類。 (我需要類似於System.Threading.Timer的東西)。
我需要一個定時器類,它應該提供啓動/停止/啓用/禁用的功能,並且應該不是用戶界面。城域應用程序中受控制的非UI定時器(.NET)
我看到2個選項
DispatcherTimer - >有不同之處在於它是在UI線程上執行
ThreadPoolTimer所有功能 - >沒有超過週期定時器控制。
我想通過線程池計時器創建包裝,但似乎非常複雜,因爲沒有/有限的控制權。
如何爲所述場景設計一個計時器類。 (我需要類似於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();
}
}
我能創造一個時鐘用下面的代碼:
ThreadPoolTimer Timer1 = ThreadPoolTimer.CreatePeriodicTimer(Timer1_ElapsedHandler, TimeSpan.FromSeconds(1));
clockTick = false;
UpdateLoop();
爲此,您需要一個事件處理程序,在我的時鐘此設置計時器滴答:
public void Timer1_ElapsedHandler(ThreadPoolTimer timer)
{
clockTick = true;
}
然後更新GUI(或任何你需要的),有一個更新循環:
public async void UpdateLoop()
{
do
{
await Task.Delay(100);
} while (!clockTick);
ClockTextBlock.Text = DateTime.Now.ToString();
clockTick = false;
UpdateLoop();
}
大概將它包裝在一個類中並清理一下可能會爲您提供非UI定時器的基礎。
感謝您的良好實施。 我會使用它,並在需要時進行更新。但大部分基礎工作已經完成。 線程安全/同步似乎是唯一關心的問題。 – Tilak
很酷。順便說一句 - 我將它與示例一起添加到WinRT XAML Toolkit(http://bit.ly/WinRTXamlToolkit)中,並稍微調整了間隔,以便平均Tick頻率更接近Interval值所指示的值。即使沒有這些調整,它實際上似乎比DispatcherTimer更精確。 –
存在WinRTXamlToolKit,我不知道。感謝分享,如果你有一些未決的項目/想法,我很樂意貢獻。 – Tilak