[英]Background timer to update UI?
我的申請有一點問題。
我想每 10 秒更新一次 UI 上的內容。 我首先為此使用了DispatcherTimer
,但它會在短時間內阻塞我的 UI,因為更新方法需要從 Web 加載某些內容,而此操作需要一些時間。 現在我想到了某種后台工作者,我找到了 BackgroundTasks。
后台任務的問題是,據我所知,即使應用程序被暫停,它們也應該作為更新程序。 我不需要那個。 我只想在我的應用程序正在運行時更新,而不是在它被暫停時更新。
有什么好的方法可以解決這個問題嗎? 對此有何建議?
提前致謝!
你需要兩件事:
計時器
您可以以 10 秒的間隔更新System.Timers.Timer
的 UI。
調度員
您需要使用Dispatcher.Invoke
來更改 UI,而無需持有主 UI 線程。 相反,方法Process
應該在一個單獨的線程( Timer
方法)上調用,而不是主 UI 線程,並在其中使用Dispatcher
來提醒主 UI 線程發生變化。
Process() // method to be called after regular interval in Timer { // lengthy process, ie data fetching and processing etc. // here comes the UI update part Dispatcher.Invoke((Action)delegate() { /* update UI */ }); }
您需要創建一個線程來運行從網站獲取和處理信息的代碼部分。 這樣,您的表單將不會猶豫,因為它將位於與處理部分不同的線程上。
這篇關於代碼項目的文章應該會讓你開始。
其他答案缺少適當的清理:當計時器在窗口關閉的確切時刻觸發時,我會在嘗試運行Dispatcher.Invoke
時得到一個未捕獲的 TaskCanceledException 。 我沒有在其他問題中找到有關此問題的幫助。 我能夠通過在關閉窗口時取消注冊計時器回調來解決它。
public partial class MainWindow : Window
{
Timer clockTimer = null;
public MainWindow()
{
clockTimer = new Timer(1.0); // 1 ms update to test for TaskCanceledException
clockTimer.Elapsed += Timer_Elapsed;
clockTimer.AutoReset = true;
clockTimer.Start();
Closed += (object sender, EventArgs e) => { clockTimer.Elapsed -= Timer_Elapsed; };
}
private void Timer_Elapsed(object sender, ElapsedEventArgs e) {
var now = DateTime.Now;
Dispatcher.Invoke((Action)delegate () {
UpdateTime(now);
});
}
}
顯然,如果重新顯示窗口,這不是一個好主意。 我嘗試添加一個 dtor,但它永遠不會被調用,可能是由於循環依賴。
免責聲明:我不懂 C#,所以這可能不是最好或正確的做事方式。
此外,您可以啟動一個計時器,該計時器具有一個已過事件,每次計時器經過某個時間周期時都會發生該事件。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.