2009-07-29 6 views
1

두 개의 변수가있는 간단한 클래스와 OnTimerTick에서 호출되는 Close 함수가 있습니다. 매우 드물 긴하지만 Close() 함수에서 NullReferenceException이 발생하지만 이러한 경우가 무엇인지 이해하지 못합니다. 누군가 설명 할 수 있니?System.Windows.Forms.Timer tick 이벤트에서 NullReferenceException이 발생합니다.

System.Windows.Forms.Timer timer = new Timer(); 
//timer.Tick is wired up in Constructor to OnTimerTick 

private void OnTimerTick(object sender, EventArgs e) 
{ 
    timer.Tick -= OnTimerTick; 
    Close(); 
} 

private void Close() 
{ 
    if (varOne != null) 
    { 
     varOne.SomeEvent -= onSomeEvent; 
     varOne.Dispose(); 
     varOne = null; 
    } 

    if (varTwo != null) 
    { 
     varTwo.AnotherEvent -= onAnotherEvent; 
     varTwo.Dispose(); 
     varTwo = null; 
    } 
} 
+0

아마도 varOne과 varTwo가 무엇인지에 따라 많이 달라집니다. –

+0

디버거에서 예외가 발생한 행을 볼 수 없습니까? –

+0

@monkey_p 디버그 세션 중에이 프로그램을 만난 적이 없습니다. – Raminder

답변

1

다른 스레드가 당신의 변수를 돌연변이없는 것을 가정하고 onSomeEventonAnotherEvent는 현재 인스턴스에있는 가정 (즉,이 Null 참조의 기회는) 아마도 가장 가능성있는 것은 Dispose()가 던지는 것이 없다 ?

이것은 일반적으로 오류 상태에있을 때 가능합니다 (실제로 WCF를 괴롭힘). 처분을 래핑 해보십시오.

오. 또한 varTwo에는 간단한 이벤트 핸들러가 있다고 가정합니다. 그것은 또한 이 가능하며, 구독 취소가 실패하는 경우에는입니다. 예를 들어,이 EventHandlerList를 사용하고 이미 그것을 멀리 던져 경우 ...

그래서 함께 그 퍼팅, 뭔가 같은 :

// very paranoid cleanup 
try {varOne.SomeEvent -= onSomeEvent; } 
catch (Exception ex) { Trace.WriteLine(ex); } // best endeavours... 
try { varOne.Dispose(); } 
catch (Exception ex) { Trace.WriteLine(ex); } // best endeavours... 

는 일반적으로 편집증이 유형은 필요하지 않습니다; 그러나 때로는 그렇습니다.

+0

글쎄, 스택 추적은 Close 함수가 throw하는 것을 보여줍니다. Dispose 또는 이벤트 구독 취소의 경우 스택 추적에 반영되지 않아야합니다. – Raminder

+0

스택 추적이있을 수 있습니다. 특히 (JIT) 인라이닝과 같은 최적화 기능이있는 릴리스에서. –

+0

글쎄, 스택 추적은 내 경우에 거짓말을했다. – Raminder

관련 문제