簡體   English   中英

后台計時器更新用戶界面?

[英]Background timer to update UI?

我的申請有一點問題。
我想每 10 秒更新一次 UI 上的內容。 我首先為此使用了DispatcherTimer ,但它會在短時間內阻塞我的 UI,因為更新方法需要從 Web 加載某些內容,而此操作需要一些時間。 現在我想到了某種后台工作者,我找到了 BackgroundTasks。
后台任務的問題是,據我所知,即使應用程序被暫停,它們也應該作為更新程序。 我不需要那個。 我只想在我的應用程序正在運行時更新,而不是在它被暫停時更新。

有什么好的方法可以解決這個問題嗎? 對此有何建議?

提前致謝!

你需要兩件事:

  1. 計時器

    您可以以 10 秒的間隔更新System.Timers.Timer的 UI。

  2. 調度員

    您需要使用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#,所以這可能不是最好或正確的做事方式。

此外,您可以啟動一個計時器,該計時器具有一個已過事件,每次計時器經過某個時間周期時都會發生該事件。

  1. http://www.dotnetperls.com/timer

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM