Nic*_*dko 2 c# xaml multithreading uwp
我有一个UWP应用程序,通过SignalR接收动态更新.我正在使用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);
});
}
Run Code Online (Sandbox Code Playgroud)
然后在模型类的内部我有这个代码(在WorkOrderLine类上有另一个子observablecollection):
private void TrolleyAllocations_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
RaisePropertyChanged("WorkOrderLineItems");
ForegroundColor = GetForegroundColour();
}
Run Code Online (Sandbox Code Playgroud)
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;
}
}
Run Code Online (Sandbox Code Playgroud)
现在,在new SolidColorBrush()抛出任何wollowing异常时:
The application called an interface that was marshalled for a different thread. (Exception from HRESULT: 0x8001010E (RPC_E_WRONG_THREAD))
Run Code Online (Sandbox Code Playgroud)
在最近的更改之前,我在x中使用了Conveter:Bind来完成GetForegroundColor方法正在做的工作(我决定改变由于性能命中转换器引起的方法) - 并且它工作得很好.我也正在更新一些其他数据绑定属性 - 更新UI(代码省略),这很好用.
任何想法都会非常感激.这让我疯了.
您需要在主线程上运行模型的更改.我在使用MVVM的UWP中遇到了同样的问题.
我认为您需要使用调度程序包装事件的处理程序代码,以便在UI线程上运行它.
private void TrolleyAllocations_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
RaisePropertyChanged("WorkOrderLineItems");
ForegroundColor = GetForegroundColour();
}
}
Run Code Online (Sandbox Code Playgroud)
现在你的处理程序被调用并从后台任务中解雇,因此GetForegroundColor()在同一个线程上.
| 归档时间: |
|
| 查看次数: |
583 次 |
| 最近记录: |