2016-10-12 13 views
0

Mvvm light 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

호출 된 비동기 방식의 시도/캐치 불행하게도 어떤 차이를 만드는되지 않는 이유는 무엇입니까?

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

편집 내가 비동기를 활용하고 relayCommand 된 방법은 나의 제외 할 아무것도 없었다 밝혀졌다

3. 문제가 해결되었습니다.

+2

'InnerException'을 검사하지 않고'TargetInvocationException'에 대해 언급하는 것은 의미가 거의 없습니다. –

+0

'InnerException'이 비어 있거나 그것을 보는 방법을 모르겠습니다. 예외 설정에서 나는 Visual Studio 2015를 사용하고있다. (Common Language Runtime Exections)를 사용했다. – ajr

+1

예외가 발생하자마자 Visual Studio를 디버거로 분해함으로써 실제 오류가 발생하는 경우가있다. 예외 창에서이를 수행 할 수 있습니다. "공용 언어 런타임"을 선택하고 오류가 발생하도록하십시오. 그 일이 끝나면 그 행동을 꺼야합니다. 그 행동은 매우 성가 시게 될 수 있습니다. https://blogs.msdn.microsoft.com/visualstudioalm/2015/02/23/the-new-exception-settings-window-in-visual-studio-2015/ –

답변

2

당신은 처리되지 않은 예외 당신이 예외가 async void 방법 (즉, 람다 당신이 RelayCommand에 전달하는)를 탈출이 언제든지 볼 수 있습니다.

정상적인 동작입니다. TargetInvocationException 래퍼를 제외하고는 동기 RelayCommand 람다에서 볼 수있는 것과 동일한 동작입니다. 다른 사람들이 언급했듯이 실제의 기본 예외를 보려면 InnerException을 검사하십시오. 당신이 캐치 이러한 예외로합니다

, 당신은 try/catchasync void 방법의 전체 몸을 감싸합니다. 이것은 가능하지만 람다 안에서 다소 어색함 :

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

그러나 그것은 정말 어색해지고 있습니다.

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

아쉽게도이 수정으로도 예외가 catch되지 않습니다. 코드는'try/catch' 블록을 멋지게 종료하고'AddDeviceClickExecute'를 호출 한'relayCommand'가 종료 된 직후'TargetInvocationException'을 만나게됩니다. 자세한 내용은이 예외가 항상 발생하는 것은 아닙니다. – ajr

+0

@ajr : 문제를 재현하는 데 필요한 최소 코드 양을 줄이십시오. –

+0

실제로 ICollectionView LiveFiltering 기능과 관련된 예외 소스를 찾을 수있었습니다. 왜 그런 일이 일어 났는지는 모르지만, 일반적인'collection.Filter = FilterIfConnected; '접근법으로 되돌아 가서 모든 것이 현재로서는 비교적 잘 된 것 같습니다. – ajr