System.NullReferenceException: Object reference not set to an instance of an object.
at Cycle_Box.CycleBox.CycleBox_FormClosing(Object sender, FormClosingEventArgs e)
I can make some suggestions.
- Assume that everything is broken, or at least not ideal.
- Presume that the user is going to provide data in a format or manner that you just didn't expect. If you use a textbox for a number, the user will type "One".
- Assume that hardware breaks in the middle of what you are doing, so you have to recover.
- Take a few extra lines of code to get standards like the boot drive, the number thousands seperator etc. Don't assume that you have a C: drive or that a comma is the separator because not everyone is in America.
- Check that files/folders exist, even if you just did a call to make it: You may not have permissions.
- Don't assume the harddrive has room for what you are doing: They do fill up. Usually right in the middle of you writing to your log file.
- Get used to placing breakpoints and walking through the code line by line. Double check EVERYTHING on every line. Keep the "Locals" and "Autos" windows open so you can see your values.
- Put a breakpoint on line 1.
- When the code stops there, walk through line by line with F-10.
- Check the values of your assumptions.
- Stop. Breath. Relax. Then reason out the problem. Cut it down by sections or halves. "The value was good here, then at this method it wasn't. Where did it go between 'A' and 'B'?"
- Range check and validate values. Confirm that you didn't get a zero when you are only set to accept 1-10. Confirm your objects and values aren't null. Initialize them to a known default if possible. If a selection can be from 0-10, then initialize to -1: Now you have something to check for.
In the case of a null reference exception you know exactly where it happens because the compiler should break on that line. Just hover the mouse over the objects and the tooltip will show you the values. See which is null.
Now, if this doesn't happen on your test machine, but only in the real world...
A) VMware. A great product that lets you have virtual computers on your computer. You can test in a dozen different OS versions without a dozen different PCs. Best of all, it integrates with Visual Studio so you can have VS throw the project being debugged directly into VMware. You can use its remote debug feature to build in XP, yet debug in Win2k
B) In the method that is failing you need to add more robust value validation before running code. You can't assume things are not null.
Example: - Graphics g = Graphics.FromImage(m_Undo);
Presumes that m_Undo must be good (not null)(actually exists)(not in use)(you have permissions)(doesn't time out when accessed). If that assumption fails so does the program, because you can't make anything from a file if the file is null. Get used to
validating data and assumptions in your code if you want it to be robust. For example:
- if (m_Undo != null)
-
{
-
bool bSuccess = false;
-
// Do your thing here, for example:
-
if (myObject != null) bSuccess = true;
-
// or
-
if (denominator > 0) bSuccess = true;
-
// or
-
if (MyFunctionReturn != Failed) bSuccess = true;
-
// Hurray, your thing worked!
-
-
if (bSuccess)
-
{
-
// Then do this other thing if it worked
-
}
-
else
-
{
-
// Then do the failure recovery part / user failure message
-
}
-
-
return bSuccess; // If you want the calling method to know if it worked.
-
}
It could be that your properties of 'closing' or 'cycling' are null... or the log. If the application is quiting maybe the log has already been disposed of by the time this form tries to close and wants to access it.
Try putting in more log entries to see how far it gets before failure
- private void CycleBox_FormClosing(object sender, FormClosingEventArgs e)
-
{
-
Log.writeMessage(log, "Form closing");
-
-
// Set the boolean flags to stop cycling in worker thread.
-
// Closing prevent dialogs from opening
-
Log.writeMessage(log, "closing true");
-
-
closing = true;
-
// Cycling tells the thread to stop running.
-
Log.writeMessage(log, "cycling true");
-
-
cycling = false;
-
Log.writeMessage(log, "cycling false");
-
-
// If the thread is created and running.
-
if (workerThread != null && workerThread.IsAlive)
-
{
-
// Tell the user we are working on closing.
-
Log.writeMessage(log, "Finishing Cycle");
-
// Wait for current cycle to complete.
-
workerThread.Join();
-
// Get rid of the dialog to the user.
-
Log.closeMessage();
-
}
-
}