C# System.Windows.Forms.Timer tick事件中发生NullReferenceException异常

C# System.Windows.Forms.Timer tick事件中发生NullReferenceException异常,c#,.net,C#,.net,我有一个包含两个变量的简单类和一个从OnTimerTick调用的Close函数。在非常罕见的情况下,Close()函数中会出现NullReferenceException,但我无法理解这些情况可能是什么。有人能解释一下吗 System.Windows.Forms.Timer timer = new Timer(); //timer.Tick is wired up in Constructor to OnTimerTick private void OnTimerTick(object sen

我有一个包含两个变量的简单类和一个从OnTimerTick调用的Close函数。在非常罕见的情况下,Close()函数中会出现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;
    }
}

假设没有其他线程正在变异变量,并且假设当前实例上存在
onSomeEvent
onNotherEvent
(即不存在空引用),那么最有可能的情况可能是
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...

正常情况下,这种偏执是没有必要的;但是有时候是这样的。

假设没有其他线程正在改变您的变量,并且假设当前实例上有
onSomeEvent
onnotherevent
(即不可能有空引用),那么最有可能的事情可能是
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...

正常情况下,这种偏执是没有必要的;但有时是这样。

这可能很大程度上取决于varOne和varTwo是什么。你在调试器中看不到异常发生在哪一行吗?@monkey\p我在调试会话中从未遇到过它。这可能很大程度上取决于varOne和varTwo是什么。你在调试器中看不到异常发生在哪一行吗?@monkey\p在调试会话期间从未遇到过它。堆栈跟踪显示Close函数抛出。如果抛出的是Dispose或event unsubscribe,则不应反映在堆栈跟踪中。堆栈跟踪可能存在。特别是在具有优化(JIT)内联的发行版中。堆栈跟踪确实存在于我的案例中。堆栈跟踪显示关闭函数抛出。如果抛出的是Dispose或event unsubscribe,则不应反映在堆栈跟踪中。堆栈跟踪可能存在。特别是在具有优化(JIT)内联的发行版中,堆栈跟踪确实存在于我的案例中。