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
,我认为这是预期的行为。
我使用信号 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);
});
作为
但是,对于解决方案,我建议使用更通用的 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
,我认为这是预期的行为。