Exception when closing threaded splash screen using Invoke

G

Guest

Hi,

I have an application that seems to crash upon startup in isolated
situations (double clicking an associated file). I looked into it a little
bit and noticed it was getting to the point where it was closing a splash
screen that the problem occurred.
Example:
In the main form -
// close the splash screen
SplashForm.CloseForm();
In the splash form -
in splash constructor:
closeDelegate = new CloseDelegate(this.Close);
hideDelegate = new HideDelegate(this.Hide);
...
public static void CloseForm()
{
if (splash != null)
{
splash.Invoke(splash.closeDelegate, null);
Application.DoEvents();
splash = null;
thread = null;
}
}
public static HideForm()
{
splash.Invoke(splash.hideDelegate, null);
Application.DoEvents();
}

When closing the form, the splash.Invoke... line throws a NullReference
exception, but neither closeDelegate nor splash is null, and appear to be
instantiated properly.
I suspect there is some kind of odd timing/threading issue going on since
this only happens on Win2000 machines. To make things a little weirder, if I
hide the form first by calling this instead:

// hide the splash screen
SplashForm.HideForm();
SplashForm.CloseForm();

The splash form is closed, the program continues on, and there is no
problem. Any ideas on what the possible cause is here, and why it might be
different on Win2k compared to XP?

Jon Hiley
 
P

Peter Duniho

When closing the form, the splash.Invoke... line throws a NullReference
exception, but neither closeDelegate nor splash is null, and appear to be
instantiated properly.

Well, _something_ is null. If not the closeDelegate or splash variable,
then what? .NET doesn't throw NullReference exceptions just for the fun
of it. :)

One thing I note is that you don't synchronize access to the splash
variable. So you could have a race condition where two different threads
are using it and then setting it to null. Whichever thread wins the race
gets to set the variable to null before the other is done with it, which
would cause a null exception. Of course, you didn't post nearly enough
code for anyone to be able to identify something like that, but it's a
possibility given the little code that you did post.

If you do post more code, don't post all of it. Just pare down your code
to the bare minimum required in order to reproduce the problem, while
still providing a complete program that can be compiled.
I suspect there is some kind of odd timing/threading issue going on since
this only happens on Win2000 machines. To make things a little weirder,
if I
hide the form first by calling this instead:

// hide the splash screen
SplashForm.HideForm();
SplashForm.CloseForm();

The splash form is closed, the program continues on, and there is no
problem.

All that shows is suggest that you do in fact have some sort of
timing-related thread issue. Basically, if you have a reproducible error
case, often when you change the exact operations you do, especially if
doing so affects the timing of the code, the error goes away. However,
since many thread-related bugs are timing-related, that's not really
useful information, and it doesn't mean you've actually fixed the bug. It
just means you've made it harder to debug, because the error no longer
happens.

Pete
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top