2016-06-08 3 views
0

다음 코드는 System.NullReferenceException 제기된다이것이 null 참조 예외를 생성하는 방법은 무엇입니까?

Windows.UI.Xaml.Data.CollectionViewSource.put_Source에서 구체적
 if (!App.AppIsSuspending && groupedItemsViewSource != null) 
      groupedItemsViewSource.Source = null; 

(개체 값).

저는 이것이 어떻게 또는 왜 일어날 수 있는지 이해하기 위해 정말로 애 쓰고 있습니다. 이것에 대해 나는 무엇을 잘못 생각하고 있는가?

나는 그것을 try ... catch로 감쌀 수 있다고 생각하지만 실제로 왜 폭발하는지 이해하지 못한다.

전화가 Windows Phone 8.1 또는 Windows Mobile을 실행하는 경우 원격 측정 정보가 충분하지 않더라도 Windows Phone에서 실행되는 WinRT 앱에 있습니다.

업데이트 : 그냥 명확히하기 위해 예외는 실제로 CollectionViewSource.put_source에서 발생합니다. 나는 이전 값을 공개하려고하는 기본 코드에 버그가 있다고 의심하지만 null 일 수 있는지 테스트하지는 않습니다. 실제 예외 레코드는 다음과 같습니다.

System.NullReferenceException: Object reference not set to an instance of an object. 
    at Windows.UI.Xaml.Data.CollectionViewSource.put_Source(Object value) 
    at Relative_History.ViewEvent.<OnNavigatedFrom>d__12.MoveNext() 
--- End of stack trace from previous location where exception was thrown --- 
    at System.Runtime.CompilerServices.AsyncMethodBuilderCore.<ThrowAsync>b__3(Object state) 
    at System.Threading.WinRTSynchronizationContext.Invoker.InvokeCore() 

내 이론을 테스트하기 위해 작은 데모 응용 프로그램을 작성하려고합니다. 나는 더 많은 연구를 할 수 있기 때문에 질문을 삭제하려고했으나 사람들은 이미 대답하기 시작 했으므로 그렇게하는 것이 잘못이라고 느꼈다.

업데이트 : groupedItemsViewSource 따라서, 예외를 제기하는 페이지의 XAML에 선언 :

<Page.Resources> 
    <CollectionViewSource 
     x:Name="groupedItemsViewSource" 
     ItemsPath="GroupMembers" 
     IsSourceGrouped="True"/> 
</Page.Resources> 

그러나, 단지 않는 간단한 한 페이지 응용 프로그램 작성 :

groupedItemsViewSource.Source = null; 
을 코드 숨김에서

은 동일한 동작을 트리거하지 않습니다. WP8.1 및 W10M 에뮬레이터로 테스트했습니다.

비동기 비트가 예외 로그에도 포함되는 이유는 조금 확실하지 않습니다. 당신이 볼 수 있듯이, groupedItemsViewSource.Source = null이 라인에 이르기까지의 모든 비동기 코드가없는,

protected override async void OnNavigatedFrom(NavigationEventArgs e) 
    { 
     Debug.WriteLine("ViewEvent:OnNavigatedFrom"); 

     if (!App.AppIsSuspending && groupedItemsViewSource != null) 
      groupedItemsViewSource.Source = null; 

     if (evm != null) 
     { 
      evm.GroupBuildingCompleted -= HandleGroupBuildingCompleted; 
      await evm.CancelGroupBuilding(); 

      if (!App.AppIsSuspending) 
      { 
       evm.NoLongerInUse(); 
       evm = null; 
      } 
     } 

     navigationHelper.OnNavigatedFrom(e); 

     if (!App.AppIsSuspending) 
     { 
      this.navigationHelper.LoadState -= navigationHelper_LoadState; 
      this.navigationHelper.SaveState -= navigationHelper_SaveState; 
#if WINDOWS_APP 
      this.SizeChanged -= ViewEvent_SizeChanged; 
#endif 
     } 
    } 

과 : 전체 OnNavigatedFrom입니다.

업데이트 : 저는 여전히 비동기가 예외 스택에서 어떻게 작동하는지 파악하려고합니다. 내가 오해하고있는 것이 아니라면, Relative_History.ViewEvent.d__12.MoveNext() 에서은 기다렸다가 코드가 반환되었다고 제안 할 것입니까? 하지만 OnNavigatedFrom에서 기다리는 것은 groupedItemsViewSource.Source를 null로 설정 한 후입니다. ...

또는 예외 스택 추적을 잘못 해석하고 있습니까?

+1

디버그가 null 인 변수를 확인하고 그 이유를 찾을 수 있습니다. –

+1

System.NullReferenceException을 보여주는 예외의 중요한 부분을 추가하십시오. –

답변

0

다른 그룹의 다른 항목 인 groupedItemsViewSource를 null로 설정 하시겠습니까?

스레드 1 :

if (!App.AppIsSuspending && groupedItemsViewSource != null) 
    groupedItemsViewSource.Source = null; 

스레드 2 :

groupedItemsViewSource = null; 

그렇다면 : 다음, 스레드 1의 코드가 체크를 한 일이 발생할 두 세트를 null로 변수를 스레드 수 있으며 이후 스레드 1은 표시된 결과를 사용하여 소스에 액세스하려고 시도합니다.

이 문제를 방지하려면 .Net의 잠금 메커니즘을 사용할 수 있습니다.

는 클래스

예컨대 :

object lockGroupedItemsViewSource = new object(); 

에 잠금 필드를 정의하고 groupedItemsViewSource에 액세스하는 모든 스레드에서 사용.

스레드 1 :

lock(lockGroupedItemsViewSource) 
{ 
    if (!App.AppIsSuspending && groupedItemsViewSource != null) 
     groupedItemsViewSource.Source = null; 
} 

스레드 2 :

lock(lockGroupedItemsViewSource) 
{ 
    groupedItemsViewSource=null; 
} 

건배

토마스

+0

코드 검색을했는데 groupedItemsViewSource를 명시 적으로 설정하지 않았습니다. XAML에서만 정의되었으며 OnNavigatedFrom이 실행을 완료하기 전에 페이지를 언로드 할 수있는 방법을 이해하기 위해 고심하고 있습니다. –

관련 문제