2011-05-03 76 views
2

我需要載入每秒(或兩個)新圖像。每秒載入新圖像

下面的代碼無法正常工作:

System.Threading.Thread.Sleep(2000); 
this.Image_LoadImage.Source = new BitmapImage(new Uri(@"D:\\connect2-1.gif")); 
System.Threading.Thread.Sleep(2000); 
this.Image_LoadImage.Source = new BitmapImage(new Uri(@"D:\\connect3-1.gif")); 

我看到的是該應用程序睡4秒鐘,然後出現的第二個圖像。

我該怎麼辦? 謝謝。

回答

5

private System.Threading.Timer timer; 
    public MainWindow() 
    { 
     InitializeComponent(); 
     timer = new System.Threading.Timer(OnTimerEllapsed, new object(), 0, 2000); 
    } 

    private void OnTimerEllapsed(object state) 
    { 
     if (!this.Dispatcher.CheckAccess()) 
     { 
      this.Dispatcher.Invoke(new Action(LoadImages)); 
     } 
    } 

    private bool switcher; 
    private void LoadImages() 
    { 
     string stringUri = switcher ? @"D:\\connect2-1.gif" : 
             @"D:\\connect3-1.gif"; 
     this.Image_LoadImage.Source = new BitmapImage(new Uri(stringUri)); 

     switcher = !switcher; 
    } 
+0

當我使用計時器,並在OnTimerEllapsed我試圖改變圖像源,我得到一個異常,說它不能訪問圖像,因爲它是由另一個線程擁有.... @Stecya – 2011-05-03 12:25:53

+0

@olia,請參閱我在.NET應用程序中更新UI時正確回答了線程安全使用定時器的問題。 – magma 2011-05-03 12:26:50

+0

@olia - 您需要切換到主線程才能使用UI元素,請參閱我的編輯 – Stecya 2011-05-03 12:30:04

5

使用計時器。

調用線程睡眠會阻塞UI線程。發現這個link你:

3

我想,你的代碼駐留在一個單一的功能,它執行主線程中使用計時器。出於這個原因,直到你的函數返回,UI纔會被更新。

在這一點上,你會留下任何狀態是在你的函數返回的時間最新這就是爲什麼你只看到你設置的最後一張照片)。

此外,請注意,通過發出Sleep()請求中間函數,您基本上阻塞了應用程序的主線程(或者您的函數運行的任何線程,但很可能是您的主線程)。在睡眠期間,您的應用程序不會簡單地響應任何事情,您的UI將凍結。

,可能會決定取消你的控制(Control.Refresh()Control.Invalidate()Control.Update()Control.Refresh()Application.DoEvents()),但這些都是一般的黑客,除非使用得當。可以使用Timer。雖然在你的具體情況下,簡單地使用GIF動畫可能是最好的解決方案。

請注意,如果您決定使用計時器System.Windows.Forms.Timer與其他計時器之間存在相當重要的差異System.Windows.Forms.Timer將盡早在主線程上運行(因此,與UI控件進行交互將是安全的,因爲您將從同一個線程執行此操作;但另一方面,它可能會稍微延遲觸發) 。相反,如果您要使用不同的計時器,您將無法直接訪問UI控件而不違反重要規則。更多關於這裏:Comparing the Timer Classes in the .NET Framework Class Library

參見: Force GUI update from UI Thread

和: Animated Gif in form using C#

0

嘗試更改它的源後刷新()的控制。

+0

正如岩漿所說,使用Refresh()或DoEvents()幾乎總是用於此目的的黑客攻擊。 – Shibumi 2011-05-03 14:48:46

+1

@Shyibumi,爲什麼?我確定我在一本書中讀到它。你可以解釋嗎? – atoMerz 2011-05-03 18:40:32

+0

關閉我的頭頂:刷新實際上會導致大量重繪工作在控制層次結構中進行。儘可能允許控件自行繪製。 DoEvents將導致隊列中的所有事件都被處理,並且所有處理程序的代碼都將被運行,而不僅僅是您的代碼。除非有很好的理由,否則帶回調方法的線程幾乎總是最好的方法。 – Shibumi 2011-05-24 21:19:56