sensei
sensei

Reputation: 7592

Timer freezes my WPF window

I have read some topics about Timer, and found out that System.Timers.Timer already has threading implemented. So I used Dispatcher.Invoke, but my Timer is still freezing my window.

My code: System.Timers.Timer

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

Next method that timer triggers:

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

And final method that is parsing from the web and assigns value to my TextBlock... Which means it takes 1-2-3 seconds to parse before it assigns value:

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;
}

So window freezes in that time. How to properly implement this? Thank you

Upvotes: 0

Views: 1090

Answers (1)

Arian Motamedi
Arian Motamedi

Reputation: 7423

Right now the whole GetLastFmCurrentSong() method is being dispatched to the UI thread, that is why it's blocking. You only need to dispatch part of the code that is trying to access the UI. To do this, first create a global Dispatcher variable for the UI thread like this:

private Dispatcher currentDispatcher = Dispatcher.CurrentDispatcher;

Change your GetSongTimer to call the GetLastFmCurrentSong() method directly (or eventually have the timer's Elapsed event call it):

private void GetSongTimer()
{
    GetLastFmCurrentSong();
}

Finally, change your GetLastFmCurrentSong() to only use the dispatcher on 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;
   }));
}

Upvotes: 1

Related Questions