无法将项目添加到ObservableCollection

时间:2019-02-02 11:54:38

标签: c# uwp signalr

我使用信号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:

在我的

  

Messages.Add(mess);

我收到数据时

2 个答案:

答案 0 :(得分:3)

作为Martin noted,您必须从其UI线程更新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 to async Task(再次,更好的可重用性和可测试性),并为每条聊天消息制作了一个新的ChatMessage,我相信这是预期的行为。

答案 1 :(得分:1)

之所以发生这种情况,是因为使用Add()ObservableCollection必须在UI线程上运行。因此,要使其正常工作,请确保在Dispatcher.RunAsync()中执行调用:

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