2017-07-13 19 views
2

SignalRを使用して動的更新を受け取るUWPアプリケーションがあります。私はTemplate10を使用しており、SignalRリスナーはViewModelクラスにあります。UWP SolidColorBrush - 別のスレッド例外のためにマーシャリングされたアプリケーションを呼び出すアプリケーション

メッセージがSignalRで受信されると、モデルが更新されます。モデルを更新するコードのブロックは、ディスパッチャ方式に包まれて:

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()にwollowing例外がスローされます。

The application called an interface that was marshalled for a different thread. (Exception from HRESULT: 0x8001010E (RPC_E_WRONG_THREAD)) 

前、私はXで最速を使用していた最近の変更に:バインドをGetForegroundColor方法がやっている仕事をするために(私は変更することを決定しましたアプローチはパフォーマンスヒットコンバータのために発生する) - それは正常に動作していた。また、他のデータバインドされたプロパティのいくつかを更新しています。これはUI(コード省略)を更新しますが、これはうまく動作します。

いずれのアイデアも高く評価されます。それは私を狂ってしまった。

+1

UIスレッドでメソッドを呼び出す必要があります(私はUWPを使用するときにXamarinフォームで同じことをする必要があります) – hugoterelle

+0

コメントありがとうございます。これは私の質問の根源です:Despatcher呼び出しでラップされたモデルを更新しています。モデルの内部でCollectionChangedイベントハンドラをトリガします。 UpdateChangedイベントは別のスレッドで呼び出されますか?更新モデルクラスへの元の呼び出しはUIスレッドに反映されるためです。 –

答えて

5

モデルの変更をメインスレッドで実行する必要があります。 MVVMを使用するUWPで同じ問題が発生しました。

UIスレッドで実行するには、イベントのハンドラコードをディスパッチャでラップする必要があると思います。

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

今、あなたのハンドラがそうGetForegroundColor()が同じスレッド上にある、と呼ばれ、バックグラウンドタスクから発射されます。

関連する問題