Можно ли использовать ReportProgress из BackgroundWorker для других целей? - PullRequest
0 голосов
/ 11 августа 2010

Я пишу приложение WPF, используя подход MVVM.В моей ViewModel у меня есть ObservableCollection.Периодически моему приложению необходимо проверять наличие новых сообщений и, если они есть, добавлять их в коллекцию ObservableCollection.

Если я пытаюсь добавить коллекцию ObservableCollection в DoWork, это не работаетиз-за проблем с синхронизацией потоков.Похоже, что самый простой способ добиться этого в потоке пользовательского интерфейса - это сделать ReportProgress () и обновить коллекцию оттуда.

Мой вопрос: философски и технически, нормально ли обновлять пользовательский интерфейс?от обработчика ReportProgress, хотя "по букве закона" я на самом деле не сообщаю о прогрессе.

Есть ли более разумный способ сделать это?

* РЕДАКТИРОВАТЬ: Код работает с использованием Dispatcher Timer *

ViewModel

class MyViewModel
{
    public ObservableCollection<string> MyList { get; set; }

    public MyViewModel()
    {
        MyList = new ObservableCollection<string>();
    }
}

"кодекс" - просто пример, а не код моего приложения.

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {

        MyViewModel mvm = new MyViewModel();
        this.DataContext = mvm;

        DispatcherTimer mytimer = new DispatcherTimer();
        mytimer.Interval = TimeSpan.FromSeconds(5.0);
        mytimer.Tick += new EventHandler(mytimer_Tick);

        mytimer.Start();


    }

    void mytimer_Tick(object sender, EventArgs e)
    {
        ((DispatcherTimer)sender).Stop();

        MyViewModel mvm = this.DataContext as MyViewModel;
        mvm.MyList.Insert(0, DateTime.Now.ToLongTimeString());

        ((DispatcherTimer)sender).Start();
    }

Похоже, это будет работать хорошо для того, что мне нужно, и не даст мне дополнительный багаж, который я не собираюсь использовать (например, отмена, работник завершен и т. Д.).

Ответы [ 3 ]

1 голос
/ 11 августа 2010

Я бы не стал это делать

Это "похоже" на то, что вызовет проблемы в будущем (возможно, когда кто-то попытается добавить функции спустя годы, возможно, когда этот код будет обновлен или портирован насреда с немного другой реализацией ReportProgress.)

Я бы просто использовал Dispatcher.BeginInvoke (я также стараюсь избегать использования Invoke, потому что он заставляет один поток ожидать другого и снижает эффективность использования многопоточности впервое место).

Но есть места, где просто использование ReportProgress является правильным выбором, вам нужно решить для себя, что лучше всего подходит для вашей конкретной ситуации (больше всего я ненавижу оценивать «лучшие практики» или «архитектуру»)."больше, чем создание действующего программного обеспечения)

1 голос
/ 11 августа 2010

Если вы реализуете функциональность типа опроса в своем приложении, возможно, имеет смысл использовать DispatcherTimer, который запускается с интервалом, вместо того, чтобы постоянно выполнять циклы внутри BackgroundWorker.*

1 голос
/ 11 августа 2010

Конечно. Вот для чего предназначен UserState EventArgs.

Причиной использования BackgroundWorker является упрощение многопоточности. В противном случае вам придется сделать что-то вроде Invoke (или BeginInvoke), чтобы обработать то же самое, для чего используется BackgroundWorker.

...