2013-08-26 93 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

谢谢。很好的解释! –