I have a UWP application that receives a dynamic updates via SignalR. I'm using Template10 and the SignalR listener is located in the ViewModel class.
When messages are received by SignalR - the Model is updated. The block of code that updates the model is wrapped in Despatcher method:
VM - method invoked by 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);
});
}
Then inside of the model class I have this code (there is another child observablecollection on WorkOrderLine class):
private void TrolleyAllocations_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
RaisePropertyChanged("WorkOrderLineItems");
ForegroundColor = GetForegroundColour();
}
The GetForegroundColor is the following:
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;
}
}
Now, on any new SolidColorBrush()
the wollowing exception is thrown:
The application called an interface that was marshalled for a different thread. (Exception from HRESULT: 0x8001010E (RPC_E_WRONG_THREAD))
Prior to the recent changes I was using the Conveter in x:Bind to do the work that GetForegroundColor method is doing (I have decided to change the approach due to the performance hit converters incur) - and it was working just fine. I'm also updating some of the other databound properties - which update UI (code omitted) and this works just fine.
Any ideas would eb greatly appreciated. It's been driving me insane.
You need to run your model's changes on the main thread. I've got the same problem in UWP using MVVM.
I think you need to wrap with a dispatcher your event's handler code in order to run it on the UI thread.
private void TrolleyAllocations_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
RaisePropertyChanged("WorkOrderLineItems");
ForegroundColor = GetForegroundColour();
}
}
Now your handler is called and fired from a background task, so GetForegroundColor()
is on the same thread.
User contributions licensed under CC BY-SA 3.0