2014-09-04 30 views
0

在應用程序中,我顯示隨時間推移或用戶單擊下一個/上一個時會旋轉的橫幅。從計時器線程的WPF UI更新

1)我需要更新Timer.Elapsed方法中的UI元素。從我發現的看來,計時器滴答是在他們自己的線程上執行的,元素的分派器應該用來更新UI。

((Image)BannerPanel.Content).Dispatcher.Invoke(new Action(() => { 
    ((Image)BannerPanel.Content).Source = GetImage(new Uri(banner.Uri, UriKind.Absolute)); 
})); 

但是拋出了InvalidOperationException

2)橫幅控制器提供NextPrevious方法,分別調用display next/previous banner。由於DisplayBanner方法嘗試顯示橫幅,當文件未找到時,它會嘗試使用WebClientAsyncFileDownloadDownloadComplete重新下載它,它會顯示圖像。我是否正確地假設定時器啓動的ElapsedNext/Previous的手動調用都可以同時發生,兩者都在它們自己的線程上運行(在UI線程上爲Previous/Next,在定時器線程上爲Elapsed),這可能導致不穩定?

+0

只需使用而不是'Timer'一個'DispatcherTimer'。 – Sheridan 2014-09-04 15:11:56

+0

每個*線程都有一個Dispatcher,因此您可能不會使用UI線程中的一個。爲了確保您可以使用Application.Current.Dispatcher對象。另請參閱[Dispatcher.CurrentDispatcher vs. Application.Current.Dispatcher](http://stackoverflow.com/questions/10448987/dispatcher-currentdispatcher-vs-application-current-dispatcher)以獲取更多信息。然而,'DispatcherTimer'是這個工作的正確工具,因爲它避免了使用'Dispatcher'對象的任何需要。 – Sheridan 2014-09-04 15:34:58

回答

1

您應該使用DispatcherTimer類而不是常規Timer進行調查。它旨在與WPF UI一起使用,僅用於這些類型的用途,因爲它在Dispatcher線程上運行。

更多信息:System.Windows.Threading.DispatcherTimer

+0

好的,但是你知道我正在嘗試執行調度程序調用的問題嗎?僅供參考。 – pikausp 2014-09-04 15:17:01

+0

@pikausp,請參閱我對你的問題的評論。這在我看來是最好的答案。 – Sheridan 2014-09-04 15:36:49

1

嘗試使用應用程序來代替,

Application.Current.Dispatcher.Invoke(new Action(() => 
{ 
    ((Image)BannerPanel.Content).Source = GetImage(new Uri(banner.Uri, UriKind.Absolute)); 
}); 
+0

它不再崩潰,但我轉而使用其他人推薦的DispatcherTimer。 – pikausp 2014-09-04 15:41:43

+0

@pikausp,是的,當涉及到你的情況時,DispatcherTimer更具有熱門性。不過,這是另一種選擇。我會建議使用Application.Current每當你想做一個Invoke或BeginInvoke。 – 2014-09-04 15:44:33