Не удается добавить элемент в ObservableCollection - PullRequest
0 голосов
/ 02 февраля 2019

Я использую ядро ​​сигнала R для отправки мне списка сообщений, но это происходит

public ObservableCollection<ChatMessage> Messages { get; set; } = new ObservableCollection<ChatMessage>();

public async void InitSignalRAsync()
    {
        ChatMessage mess = new ChatMessage();
        hubConnection = new HubConnectionBuilder().WithUrl("http://localhost:5000/chatHub").Build();
        await hubConnection.StartAsync();
        hubConnection.On<string, string>("ReceiveMessage", (user, message) =>
        {
            mess.user = user;
            mess.message = message;
            Messages.Add(mess);
        });
    }

Я получил ошибку

System.Runtime.InteropServices.COMException:

на моем

Сообщения. Добавить (беспорядок);

при получении данных

Ответы [ 2 ]

0 голосов
/ 03 февраля 2019

Как заметил Мартин , вы должны обновить компоненты ViewModel из их потока пользовательского интерфейса.

Однако для решения я рекомендую использовать более универсальный SynchronizationContext, а не UWP-специфический Dispatcher класс.Используя более общий тип, ваш код более пригоден для повторного использования и более тестируем.

Например:

public ObservableCollection<ChatMessage> Messages { get; set; } = new ObservableCollection<ChatMessage>();

public async Task InitSignalRAsync()
{
  var context = SynchronizationContext.Current;
  hubConnection = new HubConnectionBuilder().WithUrl("http://localhost:5000/chatHub").Build();
  await hubConnection.StartAsync();
  hubConnection.On<string, string>("ReceiveMessage", (user, message) =>
  {
    var mess = new ChatMessage
    {
      user = user,
      message = message,
    };
    context.Post(_ => Messages.Add(mess));
  });
}

Я также изменил ваш async void на async Task(опять же, улучшенное повторное использование и тестируемость), и сделал новый ChatMessage для каждого сообщения чата, которое, я считаю, является предполагаемым поведением.

0 голосов
/ 02 февраля 2019

Это происходит потому, что Add() должен работать в потоке пользовательского интерфейса при использовании ObservableCollection.Поэтому, чтобы это работало, обязательно выполните вызов в Dispatcher.RunAsync():

Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { 
    Messages.Add(mess);
 });
...