Обновить пользовательский интерфейс с таймером в WPF (с BackgroundWorker?) - PullRequest
11 голосов
/ 20 октября 2010

У нас есть приложение в WPF, которое показывает данные через ObservableCollection.Через 5 минут я хочу обновить данные.

Я подумал, что мог бы использовать объект System.Timers.Timer для его события Elapsed, а затем вызвать BackgroundWorker для вызова метода, запускающего задание.Этот метод относится к классу ViewModel.

Но похоже, что есть проблема с потоками.

Итак, я попытался с Dispatcher, но снова то же самое.

Вот мой(упрощенный и не оптимизированный) код:

/// <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();
        }
    }
}

Есть предложения о том, как мне поступить?

Ответы [ 2 ]

40 голосов
/ 20 октября 2010

Почему бы не использовать DispatcherTimer?Это уже будет "галочка" в ветке диспетчера.

Кроме того, трудно сказать, что не так, просто из вашего описания "есть проблема с потоками".

2 голосов
/ 13 июня 2014

Этот ответ объясняет проблему использования Timer против DispatcherTimer при обновлении пользовательского интерфейса.https://stackoverflow.com/a/2258909/1698182

Я не пробовал это, но для периодических рабочих элементов, которые будут использовать поток, сделайте основную часть работы, которая выглядит так, как будто она сделает свое дело.http://msdn.microsoft.com/en-us/library/windows/apps/xaml/jj248676.aspx

...