【发布时间】:2017-12-18 19:41:56
【问题描述】:
我有一个通过 SignalR 接收动态更新的 UWP 应用程序。我使用的是 Template10,SignalR 监听器位于 ViewModel 类中。
当 SignalR 收到消息时 - 模型会更新。更新模型的代码块包装在 Despatcher 方法中:
VM - SignalR 调用的方法:
private async void AddOrder(WorkOrder order)
{
await Windows.ApplicationModel.Core.CoreApplication.MainView.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
order.Lines = new ObservableCollection<WorkOrderLine>(order.Lines.OrderByDescending(m => m.QtyScanned < m.Qty);
this.Orders.Add(order);
});
}
然后在模型类内部我有这段代码(WorkOrderLine 类上还有另一个子 observablecollection):
private void TrolleyAllocations_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
RaisePropertyChanged("WorkOrderLineItems");
ForegroundColor = GetForegroundColour();
}
GetForegroundColor 如下:
private SolidColorBrush GetForegroundColour()
{
try
{
if (WorkOrderLineItems.Where(m => m.Status == UnitStatus.Other).Any())
{
return new SolidColorBrush(Colors.Red);
}
else if (WorkOrderLineItems.Where(m => m.Status == UnitStatus.AssemblyLine).Any())
{
return new SolidColorBrush(Colors.Green);
}
else if (WorkOrderLineItems.Where(m => m.Status == UnitStatus.PreLoad).Any())
{
return new SolidColorBrush(Colors.Black);
}
else if (WorkOrderLineItems.Where(m => m.Status == UnitStatus.FullAndComplete).Any())
{
return new SolidColorBrush(Colors.LightGray);
}
return new SolidColorBrush(Colors.Black);
}
catch (Exception ex)
{
Debug.WriteLine($"Exception in foreground colour: {ex.Message} {ex.StackTrace}");
return null;
}
}
现在,在任何new SolidColorBrush() 上都会抛出异常:
The application called an interface that was marshalled for a different thread. (Exception from HRESULT: 0x8001010E (RPC_E_WRONG_THREAD))
在最近的更改之前,我在 x:Bind 中使用 Conveter 来完成 GetForegroundColor 方法正在做的工作(由于转换器会导致性能下降,我决定更改该方法) - 它工作得很好。我还更新了一些其他数据绑定属性 - 更新 UI(代码省略),这工作得很好。
任何想法都将不胜感激。这让我发疯了。
【问题讨论】:
-
您需要在 UI Thread 中调用该方法(我需要在使用 UWP 时在 Xamarin Forms 上执行相同操作)
-
感谢您的评论。这是我的问题的根源:所以我正在更新包装在 Despatcher 调用中的模型,然后触发模型内部的调用 CollectionChanged 事件处理程序。是否在不同的线程上调用了 CollectionChanged 事件,因为对更新模型类的原始调用是在 UI 线程上进行的。
标签: c# multithreading xaml uwp