C # Singleton UI Threading Проблема - PullRequest
2 голосов
/ 24 января 2012

Я пользуюсь услугой, написанной кем-то другим, которая получает рыночные данные.Он подключается к их серверу, и вы отправляете ему символ, и он отправляет обратно данные.Ну, я пытаюсь использовать его, чтобы открыть несколько представлений, чтобы вы могли получить рыночные данные для более чем одного символа.Это делается так, что моя ViewModel подписывается на одноэлементное событие IncomingMessage и, если сообщение содержит символ ViewModel, оно помещает его в ObservableCollection.И вот в чем проблема.

Как можно безопасно добавить сообщение о событии в мою коллекцию?

[Редактировать] Я полагаю, что исключение выдается, потому что мой ObservableCollection привязан к DataGrid в моем представлении.

Ответы [ 2 ]

3 голосов
/ 24 января 2012

ObservableCollection<T> обычно не может быть обновлено из фоновых тем. Вам нужно использовать Dispatcher.Invoke() или Dispatcher.BeginInvoke(), чтобы обеспечить добавление данных в поток, к которому принадлежит коллекция.

Application.Current.Dispatcher.Invoke((Action)(() => myObservableCollection.Add(value)));

Это довольно распространенная задача, стоит создать метод расширения, который позаботится об этом:

static class ObservableCollectionExtensions
{
    internal static void InvokeAdd<T>(this ObservableCollection<T> self, T item)
    {
        Application.Current.Dispatcher.Invoke((Action<T>)self.Add, item);
    }

    internal static void BeginInvokeAdd<T>(this ObservableCollection<T> self, T item)
    {
        Application.Current.Dispatcher.BeginInvoke(new Action<T>(self.Add), item);
    }
}

Таким образом, вы можете сохранить несколько нажатий клавиш и набрать вместо этого:

myObservableCollection.InvokeAdd(value);
3 голосов
/ 24 января 2012

Вам необходимо перенаправить вызов метода Add в поток пользовательского интерфейса. В Prism это обычно делается с помощью агрегатора событий, но если вы не используете призму:

Предполагая, что у вас есть какой-то тип Tick, который представляет ваши рыночные данные, и что событие данных - это просто System.Action<Tick>:

dataSource.IncomingMessage += (tick) => Application.Current.Dispatcher.Invoke(new Action<Tick>(AddTheTick), tick);

или просто

dataSource.IncomingMessage += (tick) => Application.Current.Dispatcher.Invoke(new Action<Tick>(myObservableCollection.Add), tick);
...