tags:

views:

133

answers:

1

I have a simple class with two variables and a Close function which is called from OnTimerTick. On very rare occasions a NullReferenceException is occurring in Close() function, but I fail to understand what those occasions can be. Can somebody explain?

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;
    }
}
+1  A: 

Assuming that no other threads are mutating your variables, and assuming that onSomeEvent and onAnotherEvent are on the current instance (i.e. no chance of a null reference there), then perhaps the most likely thing is that Dispose() is throwing?

This is possible - typically when in an error-state (indeed, it plagues WCF); try wrapping the dispose.

Oh; I'm also assuming here that varTwo has simple event handlers; it is also entirely possible for an event unsubscribe to fail; for example, if it is using an EventHandlerList and has already thrown it away...

So putting those together, something like:

// 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...

Normally this type of paranoia isn't necessary; but sometimes it is.

Marc Gravell
Well, the stack trace shows that the Close function throws. If it was Dispose or event unsubscribe that threw then shouldn't that reflect in the stack trace.
Raminder
Stack traces can lie. Especially in release with optimisations such as (JIT) inlining.
Marc Gravell
Well, the stack trace did lie in my case.
Raminder