Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Refresh UI with a Timer in WPF (with BackgroundWorker?)

We have an application in WPF that shows data via ObservableCollection. After 5 minutes, I want to refresh the data.

I thought I could use the System.Timers.Timer object for its Elapsed event and then call a BackgroundWorker to call the method that starts the job. The method is on a ViewModel class.

But it seems that there's a problem the threads.

So I tried with the Dispatcher, but same thing again.

Here's my (simplified and not optimized) code :

/// <summary>
/// Initializes a new instance of the <see cref="ApplicationController"/> class.
/// </summary>
public ApplicationController()
{
    CreateDefaultTabs();

    Timer timer = new Timer(20000); //20 secs for testing purpose.
    timer.AutoReset = true;
    timer.Enabled = true;
    timer.Elapsed += new ElapsedEventHandler(OnTimeBeforeRefreshElapsed);
    timer.Start();
}

private void OnTimeBeforeRefreshElapsed(object sender, ElapsedEventArgs e)
{
    Dispatcher.CurrentDispatcher.Invoke(new Action(() => { RefreshData(); }));
    Dispatcher.CurrentDispatcher.Invoke(new Action(() => { UpdateLayout(); }));
}

private void RefreshData()
{
    foreach (object tab in _tabItems)
    {
        if (tab is TitleDetailsView)
        {
            TitleDetailsViewModel vm = ((TitleDetailsView)tab).DataContext as TitleDetailsViewModel;
            vm.Refresh();
        }
    }
}

private void UpdateLayout()
{
    foreach (object tab in _tabItems)
    {
        if (tab is TitleDetailsView)
        {
            TitleDetailsViewModel vm = ((TitleDetailsView)tab).DataContext as TitleDetailsViewModel;
            vm.HandleGetTitleBySymbolResponse();
        }
    }
}

Any suggestions on how I should proceed?

like image 269
esylvestre Avatar asked Oct 20 '10 19:10

esylvestre


2 Answers

Why not use a DispatcherTimer? That will "tick" in the dispatcher thread already.

Beyond that, it's hard to say what's wrong just from your description of "there's a problem with the threads".

like image 141
Jon Skeet Avatar answered Sep 28 '22 02:09

Jon Skeet


This answer explains the problem with using the Timer vs DispatcherTimer when updating the UI. https://stackoverflow.com/a/2258909/1698182

I have not tried this but for periodic work items that will use a thread do the bulk of the work this looks like it will do the trick. http://msdn.microsoft.com/en-us/library/windows/apps/xaml/jj248676.aspx

like image 22
Michael Shaffer Avatar answered Sep 28 '22 02:09

Michael Shaffer