C# 计时器冻结我的WPF窗口
我阅读了一些关于定时器的主题,发现System.Timers.Timer已经实现了线程化。所以我使用了Dispatcher.Invoke,但我的计时器仍然冻结了我的窗口 我的代码: 系统计时器C# 计时器冻结我的WPF窗口,c#,wpf,timer,C#,Wpf,Timer,我阅读了一些关于定时器的主题,发现System.Timers.Timer已经实现了线程化。所以我使用了Dispatcher.Invoke,但我的计时器仍然冻结了我的窗口 我的代码: 系统计时器 int seconds = 5; Timer timerGetSong = new Timer(); timerGetSong.Elapsed += (o, args) => GetSongTimer(); timerGetSong.I
int seconds = 5;
Timer timerGetSong = new Timer();
timerGetSong.Elapsed += (o, args) => GetSongTimer();
timerGetSong.Interval = 1000*seconds;
计时器触发的下一个方法:
private void GetSongTimer()
{
Dispatcher.Invoke(GetLastFmCurrentSong);
}
最后一个方法是从web解析并为我的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;
}
所以那个时候窗户冻结了。如何正确实施??谢谢现在整个
GetLastFmCurrentSong()
方法被分派到UI线程,这就是它被阻塞的原因。您只需要分派试图访问UI的部分代码。为此,首先为UI线程创建一个全局Dispatcher
变量,如下所示:
private Dispatcher currentDispatcher = Dispatcher.CurrentDispatcher;
更改GetSongTimer
以直接调用GetLastFmCurrentSong()
方法(或最终让计时器的已用事件调用它):
最后,将GetLastFmCurrentSong()
更改为仅在TextBlockNameSong.Text=track上使用dispatcher代码>:
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;
}));
}
从我所读到的内容来看,Dispatcher.Invoke并不是真正用于长时间运行的进程。理想情况下,您应该使用后台工作程序并使用ReportProgress方法来更新ui。您的整个GetLastFmCurrentSong
被调度到ui线程,这就是它被阻止的原因。您只需要分派正在访问UI的部分代码,即TextBlockNameSong.Text=track
在您的GetLastFmCurrentSong
方法中。PoweredByOrange我怎么做?第一次这样做,所以不知道用法。这样使用:你能写下这个作为答案,这样我就可以标记它。感谢you@JohnMathilda就这么做了。您不需要创建本地调度器,尽管这通常是一个好主意,尤其是在需要区分不同的调度器时。谢谢。很好的解释!
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;
}));
}