UWP SolidColorBrush - 应用程序称为为不同线程异常编组的接口

时间:2017-07-13 20:41:27

标签: c# multithreading xaml 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);
        });
    }

然后在模型类中我有这个代码(在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中使用了Conveter:Bind来完成GetForegroundColor方法正在做的工作(我已经决定改变方法,因为性能命中转换器会产生) - 而且它工作得很好。我还更新了一些其他数据绑定属性 - 更新了UI(代码省略),这很好用。

任何想法都会非常感激。它让我疯了。

1 个答案:

答案 0 :(得分:5)

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

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

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

现在你的处理程序被调用并从后台任务中解雇,所以GetForegroundColor()在同一个线程上。