UWP SolidColorBrush - 应用程序调用了一个接口,该接口是为不同的线程异常封送的



我有一个通过 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 类上还有另一个子可观察集合):

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(省略代码),这工作得很好。

任何想法将不胜感激。这让我发疯了。

您需要在主线程上运行模型的更改。 我在使用 MVVM 的 UWP 中遇到了同样的问题。

我认为您需要用调度程序包装事件的处理程序代码,以便在 UI 线程上运行它。

private void TrolleyAllocations_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
RaisePropertyChanged("WorkOrderLineItems");
ForegroundColor = GetForegroundColour();
}
}

现在,从后台任务调用和触发处理程序,因此GetForegroundColor()位于同一线程上。

最新更新