2016-10-12 20 views
0

MvvmライトRelayCommandasyncメソッドで頭痛を引き起こしています。 WPFのボタンは、以下のrelayCommandで結ばれている:メソッドAddDeviceClickExecuteが行われたときに、必ず次の例外が発生した時折保つためRelayCommandとasyncメソッドの結果: "'System.Reflection.TargetInvocationException'がmscorlib.dllで発生しました。

private RelayCommand _importDeviceCommand; 
    /// <summary> 
    /// Import device button for SelectDeviceView. 
    /// </summary> 
    public RelayCommand ImportDeviceCommand 
    { 
     get 
     { 
      return _importDeviceCommand 
        ?? (_importDeviceCommand = new RelayCommand(async() => await AddDeviceClickExecute(), 
         () => _selectedCableType != null 
          && _selectedAddDevice != null 
          && _selectedPointNames != null 
          && _selectedPointNames.Any())); 
     } 
    } 

は、私はおそらく何らかの形でそれを悪用しています。

タイプ 'System.Reflection.TargetInvocationException' の未処理の例外は

  • 可能な解決策は何がmscorlib.dllで発生した

  • ラムダメソッド呼び出しと何か関係がありますか?
  • したがって、 ラムダを使用しないようにrelayCommandをどのようにリファクタリングできますか?

EDIT 1

と呼ばれる非同期メソッド、のtry/catchは、残念ながら何の違いを作っていませんか?

private async Task AddDeviceClickExecute() 
     { 
      _linkTheSocket = true; 

      var deviceImporter = new DeviceImporterAsync2(_projectContext, _deviceContext); 

      var progress = new Progress<string>(status => 
      { 
       _importDeviceProgress = status; 
       RaisePropertyChanged("ImportDeviceProgress"); 
      }); 

      try 
      { 
       await deviceImporter.InvokeSimpleDeviceImport(UserSelectedSockets, progress); 
      } 
      catch (Exception ex) 
      { 
       MessageBox.Show(ex.ToString(), "Exception during simple device import", MessageBoxButton.OK, MessageBoxImage.Error); 
      } 
     } 

EDIT 2

次の例外がAddDeviceClickExecute終了直後に発生します。

Image of the exception

EDIT 3

は、私は非同期とrelayCommandを利用した方法は、私の例外を除いて行うこと 何もしなかったことが判明しました。問題は修正されました。

+2

'InnerException'をチェックせずに' TargetInvocationException'について言われることはめったにありません。 –

+0

'InnerException'が空であるか、それを見る方法がわかりません。例外設定で私はビジュアルスタジオ2015を使用しています(Common Language Runtime Exections)を有効にしました。 – ajr

+1

例外がスローされるとすぐにVisual Studioをデバッガにブレークさせることで、実際のエラーに陥る可能性があります。例外ウィンドウからこれを行うことができます。「Common Language Runtime」にチェックを入れ、エラーを起こさせます。あなたがやったときにそれをオフにしてください、その行動は非常に迷惑になることができます。 https://blogs.msdn.microsoft.com/visualstudioalm/2015/02/23/the-new-exception-settings-window-in-visual-studio-2015/ –

答えて

2

あなたが持っている任意の時間の例外がasync void方法(あなたがRelayCommandに渡している、すなわち、ラムダ)をエスケープ未処理の例外が表示されます。

これは正常な動作です。同期RelayCommandラムダと同じ動作ですが、TargetInvocationExceptionラッパーを除きます。他の人が指摘しているように、InnerExceptionを調べて実際の根本的な例外を確認してください。

あなたはキャッチこれらの例外にしたい場合は、try/catchasync void方法の全体体をラップする必要があります。これは可能ですが、ラムダ内でやや厄介です。

return _importDeviceCommand 
    ?? (_importDeviceCommand = new RelayCommand(async() => 
     { try { await AddDeviceClickExecute(); } catch (Exception ex) { ... } }, 
    () => _selectedCableType != null 
     && _selectedAddDevice != null 
     && _selectedPointNames != null 
     && _selectedPointNames.Any())); 

しかし、それは本当に厄介なIMOを取得しています。

private async void ImportDevice() 
{ 
    try 
    { 
    await AddDeviceClickExecute(); 
    } 
    catch (Exception ex) 
    { 
    ... 
    } 
} 

return _importDeviceCommand 
    ?? (_importDeviceCommand = new RelayCommand(ImportDevice, 
    () => _selectedCableType != null 
     && _selectedAddDevice != null 
     && _selectedPointNames != null 
     && _selectedPointNames.Any())); 
+0

残念ながら、この変更でも例外は発生しません。コードはうまく 'try/catch'ブロックを終了し、' AddDeviceClickExecute'を終了する 'relayCommand'の直後に' TargetInvocationException'が発生しました。詳細については、この例外が常に発生するとは限りません。 – ajr

+0

@ajr:問題を再現するのに必要な最小限のコードを減らしてください。 –

+0

実際、ICollectionView LiveFiltering機能に関連する例外の原因を見つけることができました。なぜそれが起こったのか分からないが、通常の 'collection.Filter = FilterIfConnected;'アプローチを使用するようにロールバックし、すべて現時点では比較的うまくいくようだ。 – ajr

関連する問題