2013-08-26 155 views
0

我已經閱讀了一些關於Timer的話題,並發現System.Timers.Timer已經實現了線程。所以我使用Dispatcher.Invoke,但我的計時器仍然凍結我的窗口。定時器凍結我的WPF窗口

我的代碼: System.Timers.Timer

 int seconds = 5; 
     Timer timerGetSong = new Timer(); 
     timerGetSong.Elapsed += (o, args) => GetSongTimer(); 
     timerGetSong.Interval = 1000*seconds; 

下一頁方法定時器觸發:

 private void GetSongTimer() 
     { 
      Dispatcher.Invoke(GetLastFmCurrentSong); 
     } 

和最後的方法是從網絡分析和價值分配到我的TextBlock .. 。這意味着它需要1-2-3秒才能分析值:

private void GetLastFmCurrentSong() 
{ 
    CQ dom = CQ.CreateFromUrl("http://www.last.fm/user/nukec"); 

    string listeningNow = dom["#recentTracks:first .dateCell:first"].Text(); 

    string track; 
    if (listeningNow.Contains("Listening now")) 
    { 
    track = dom["#recentTracks:first .subjectCell:first"].Text(); 
    track = track.Replace('\n', ' '); 
    } 
    else 
    { 
    track = "Not listening anything"; 
    } 
    TextBlockNameSong.Text = track; 
} 

那麼窗戶就凍結了。如何正確實施這個?謝謝

+0

從我讀過的內容來看,Dispatcher.Invoke並不是真正用於長時間運行的進程。理想情況下,您應該使用後臺工作人員並使用ReportProgress方法更新ui。 – JuStDaN

+2

您的整個'GetLastFmCurrentSong'正在分派到UI線程,這就是爲什麼它被阻止。你只需要在你的'GetLastFmCurrentSong'方法中調用部分訪問UI的代碼,也就是'TextBlockNameSong.Text = track;'。 – PoweredByOrange

+0

PoweredByOrange我該怎麼做?第一次做這個,所以不知道用法。 –

回答

1

現在整個GetLastFmCurrentSong()方法正在調度到UI線程,這就是爲什麼它阻塞。您只需分派部分嘗試訪問UI的代碼。要做到這一點,首先要建立這樣的UI線程的全局Dispatcher變量:

private Dispatcher currentDispatcher = Dispatcher.CurrentDispatcher; 

更改GetSongTimer直接調用GetLastFmCurrentSong()方法(或最終都定時器的Elapsed事件稱呼它):

private void GetSongTimer() 
{ 
    GetLastFmCurrentSong(); 
} 

最後,改變你的GetLastFmCurrentSong()只使用調度員TextBlockNameSong.Text = track;

private void GetLastFmCurrentSong() 
{ 
    CQ dom = CQ.CreateFromUrl("http://www.last.fm/user/nukec"); 

    string listeningNow = dom["#recentTracks:first .dateCell:first"].Text(); 

    string track; 
    if (listeningNow.Contains("Listening now")) 
    { 
    track = dom["#recentTracks:first .subjectCell:first"].Text(); 
    track = track.Replace('\n', ' '); 
    } 
    else 
    { 
    track = "Not listening anything"; 
    } 

    currentDispatcher.Invoke(new Action(() => 
    { 
     TextBlockNameSong.Text = track; 
    })); 
} 
+0

謝謝。很好的解釋! –