InteropServices.COMException 将项目添加到 ObservableCollection 时

InteropServices.COMException when adding item to ObservableCollection

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

当我收到数据时

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

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

作为 ,您必须从其 UI 线程更新 ViewModel 组件。

但是,对于解决方案,我建议使用更通用的 SynchronizationContext 而不是特定于 UWP 的 Dispatcher class。通过使用更通用的类型,您的代码的可重用性和可测试性更高。

例如:

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,我认为这是预期的行为。