By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,205 Members | 1,030 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,205 IT Pros & Developers. It's quick & easy.

Thread Closing Error on specfic machine.

Fr33dan
P: 57
Hi,

I'm having trouble with a multi-threaded program crashing on a specific machine when the worker thread is not initialized at when the _FormClosing method of my main form called.

Here is my on _FormClosing method:
Expand|Select|Wrap|Line Numbers
  1. private void CycleBox_FormClosing(object sender, FormClosingEventArgs e)
  2.         {
  3.             // Set the boolean flags to stop cycling in worker thread.
  4.             // Closing prevent dialogs from opening
  5.             closing = true;
  6.             // Cycling tells the thread to stop running.
  7.             cycling = false;
  8.  
  9.             // If the thread is created and running.
  10.             if (workerThread != null && workerThread.IsAlive)
  11.             {
  12.                 // Tell the user we are working on closing.
  13.                 Log.writeMessage(log, "Finishing Cycle");
  14.                 // Wait for current cycle to complete.
  15.                 workerThread.Join();
  16.                 // Get rid of the dialog to the user.
  17.                 Log.closeMessage();
  18.             }
  19.         }
On my development machine (Windows XP) and my test machine (Windows 2000) this works without an issue. On the computer I need it to work (Windows 2000) on it throws this error:
Expand|Select|Wrap|Line Numbers
  1. See the end of this message for details on invoking 
  2. just-in-time (JIT) debugging instead of this dialog box.
  3.  
  4. ************** Exception Text **************
  5. System.NullReferenceException: Object reference not set to an instance of an object.
  6.    at Cycle_Box.CycleBox.CycleBox_FormClosing(Object sender, FormClosingEventArgs e)
  7.    at System.Windows.Forms.Form.OnFormClosing(FormClosingEventArgs e)
  8.    at System.Windows.Forms.Form.WmClose(Message& m)
  9.    at System.Windows.Forms.Form.WndProc(Message& m)
  10.    at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
  11.    at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
  12.    at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
  13.  
  14.  
  15. ************** Loaded Assemblies **************
  16. mscorlib
  17.     Assembly Version: 2.0.0.0
  18.     Win32 Version: 2.0.50727.1433 (REDBITS.050727-1400)
  19.     CodeBase: file:///c:/WINNT/Microsoft.NET/Framework/v2.0.50727/mscorlib.dll
  20. ----------------------------------------
  21. Cycle Box
  22.     Assembly Version: 1.0.0.0
  23.     Win32 Version: 1.0.0.0
  24.     CodeBase: file:///C:/Program%20Files/Isotemp%20Research/Cycle%20Box/Cycle%20Box.exe
  25. ----------------------------------------
  26. System.Windows.Forms
  27.     Assembly Version: 2.0.0.0
  28.     Win32 Version: 2.0.50727.1433 (REDBITS.050727-1400)
  29.     CodeBase: file:///C:/WINNT/assembly/GAC_MSIL/System.Windows.Forms/2.0.0.0__b77a5c561934e089/System.Windows.Forms.dll
  30. ----------------------------------------
  31. System
  32.     Assembly Version: 2.0.0.0
  33.     Win32 Version: 2.0.50727.1433 (REDBITS.050727-1400)
  34.     CodeBase: file:///C:/WINNT/assembly/GAC_MSIL/System/2.0.0.0__b77a5c561934e089/System.dll
  35. ----------------------------------------
  36. System.Drawing
  37.     Assembly Version: 2.0.0.0
  38.     Win32 Version: 2.0.50727.1433 (REDBITS.050727-1400)
  39.     CodeBase: file:///C:/WINNT/assembly/GAC_MSIL/System.Drawing/2.0.0.0__b03f5f7f11d50a3a/System.Drawing.dll
  40. ----------------------------------------
  41. ATE
  42.     Assembly Version: 0.0.0.0
  43.     Win32 Version: 0.0.0.0
  44.     CodeBase: file:///C:/Program%20Files/Isotemp%20Research/Cycle%20Box/ATE.EXE
  45. ----------------------------------------
  46. System.Xml
  47.     Assembly Version: 2.0.0.0
  48.     Win32 Version: 2.0.50727.1433 (REDBITS.050727-1400)
  49.     CodeBase: file:///C:/WINNT/assembly/GAC_MSIL/System.Xml/2.0.0.0__b77a5c561934e089/System.Xml.dll
  50. ----------------------------------------
  51.  
  52. ************** JIT Debugging **************
  53. To enable just-in-time (JIT) debugging, the .config file for this
  54. application or computer (machine.config) must have the
  55. jitDebugging value set in the system.windows.forms section.
  56. The application must also be compiled with debugging
  57. enabled.
  58.  
  59. For example:
  60.  
  61. <configuration>
  62.     <system.windows.forms jitDebugging="true" />
  63. </configuration>
  64.  
  65. When JIT debugging is enabled, any unhandled exception
  66. will be sent to the JIT debugger registered on the computer
  67. rather than be handled by this dialog box.
  68.  
  69.  
  70.  
And I cannot figure out where the null reference is coming from. The only object a refer to I'm checking for a null reference and I'm pretty sure primitives can't be null C#
Oct 30 '09 #1
Share this Question
Share on Google+
4 Replies


tlhintoq
Expert 2.5K+
P: 3,525
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:
Expand|Select|Wrap|Line Numbers
  1. 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:
Expand|Select|Wrap|Line Numbers
  1. if (m_Undo != null)
  2. {
  3.    bool bSuccess = false;
  4.    // Do your thing here, for example:
  5.    if (myObject != null) bSuccess = true;
  6.    // or
  7.    if (denominator > 0) bSuccess = true;
  8.    // or
  9.    if (MyFunctionReturn != Failed) bSuccess = true;
  10.    // Hurray, your thing worked!
  11.  
  12.    if (bSuccess)
  13.    {
  14.       // Then do this other thing if it worked
  15.    }
  16.    else
  17.    {
  18.       // Then do the failure recovery part / user failure message
  19.    }
  20.  
  21.    return bSuccess; // If you want the calling method to know if it worked.
  22. }
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
Expand|Select|Wrap|Line Numbers
  1. private void CycleBox_FormClosing(object sender, FormClosingEventArgs e)
  2.         {
  3.                 Log.writeMessage(log, "Form closing");
  4.  
  5.             // Set the boolean flags to stop cycling in worker thread.
  6.             // Closing prevent dialogs from opening
  7.                 Log.writeMessage(log, "closing true");
  8.  
  9.             closing = true;
  10.             // Cycling tells the thread to stop running.
  11.                 Log.writeMessage(log, "cycling true");
  12.  
  13.             cycling = false;
  14.                  Log.writeMessage(log, "cycling false");
  15.  
  16.             // If the thread is created and running.
  17.             if (workerThread != null && workerThread.IsAlive)
  18.             {
  19.                 // Tell the user we are working on closing.
  20.                 Log.writeMessage(log, "Finishing Cycle");
  21.                 // Wait for current cycle to complete.
  22.                 workerThread.Join();
  23.                 // Get rid of the dialog to the user.
  24.                 Log.closeMessage();
  25.             }
  26.         }
Oct 30 '09 #2

Fr33dan
P: 57
That's good advice and I do perform a great deal of data validation and checking for my log (all encapsulated in my Log class) and I do enough here (closing and cycling are both primative bools and I get a expression is always 'true' warning if I check it).

I found my error and it is really annoying. So when I would run the code on my development machine (and testing machine) I would always use the debug build configuration so I can use the debugger (or remote debugger). Then I would switch to release before I built my Setup and Deployment project. Because of this the release build of my actual code project was never created. It was instead including an old version that was built weeks ago (before I added the data validation). By building that project before my Setup project all my problems went away.

Thanks for you help though. If I would have had trouble figuring out the problem in the actual wrong could this would have been very helpful.
Oct 30 '09 #3

tlhintoq
Expert 2.5K+
P: 3,525
Umm... The debugger still works when you pick 'Release' build.

If you have precompile commands that are tied to 'Debug' they will execute when in debug versus when in 'release'.

I do almost all of my debugging on the 'release' build. I only go to 'debug' when I want the added thousand log entries to be written and lots of extra console comments. For example:

Expand|Select|Wrap|Line Numbers
  1.             #if _DEBUG
  2.             Console.WriteLine(e.EventType.ToString());
  3.             #endif
  4.  
Oct 31 '09 #4

Fr33dan
P: 57
Oh I was not aware of that worked. Well I guess that's what I get for just assuming things about the language. Oh well, another error another lesson. Thanks for your help.
Oct 31 '09 #5

Post your reply

Sign in to post your reply or Sign up for a free account.