Presently I am attempting to create unit tests using MSTest.exe for multithreading functionality. When I run the tests, here are the errors I’m getting:
A first chance exception of type 'System.NullReferenceException' occurred in ApplicationManagement.exe
The thread 'Agent: adapter run thread for test 'UpdateDirectoryExceptionTest' with id 'a78d3e8e-e859-43aa-87aa-cf006f736dee'' (0x1150) has exited with code 0 (0x0).
The thread '<No Name>' (0x1bec) has exited with code 0 (0x0).
E, 6788, 86, 2011/10/20, 14:02:36.771, WKSTVMC0006\QTAgent32.exe, Unhandled Exception Caught, reporting through Watson: System.NullReferenceException: Object reference not set to an instance of an object.
at CommonObjects4.clsThread.StartThreadMethod.Execute() in D:\DevProjects\CommonObjects4\classes\clsThread.cs:line 23
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.runTryCode(Object userData)
at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
The program '[6788] QTAgent32.exe: Managed (v4.0.30319)' has exited with code -2 (0xfffffffe).
The program '[1120] ApplicationManagement.vshost.exe: Managed (v4.0.30319)' has exited with code 0 (0x0).
If I run the UpdateDirectoryExceptionTest by itself in Visual Studio, it passes with no problem, but when I run the entire suite of unit tests, I receive the above error. Here is the function that I recently started testing, which I think is related to the error:
public Thread StartClassThread(ref Thread ThreadObject, ThreadMethod MethodObject)
{
System.Threading.Thread startClassThreadReturn = null;
try
{
if (ThreadObject == null && MethodObject == null)
{
throw new ApplicationException("Cannot have both ThreadObject and MethodObject as null parameters in call to StartClassThread.");
}
StartThreadMethod objMethod = new StartThreadMethod();
objMethod.objThreadMethod = MethodObject;
if (!(ThreadObject == null))
{
if (ThreadObject.ThreadState != System.Threading.ThreadState.Stopped)
{
// Do nothing
}
}
if (!(ThreadObject == null))
{
if (ThreadObject.ThreadState == System.Threading.ThreadState.Stopped
| ThreadObject.ThreadState == System.Threading.ThreadState.Aborted
| ThreadObject.ThreadState == System.Threading.ThreadState.Unstarted)
{
ThreadObject = null;
ThreadObject = new Thread( new System.Threading.ThreadStart( objMethod.Execute ) );
ThreadObject.Start();
}
}
else
{
ThreadObject = new Thread( new System.Threading.ThreadStart( objMethod.Execute ) );
ThreadObject.Start();
}
return ThreadObject;
}
catch (Exception excException)
{
ZEGApp.clsMain.objApplicationAudit.AuditMethodError(excException, System.Reflection.MethodInfo.GetCurrentMethod().DeclaringType.FullName + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + " - " + excException.StackTrace);
}
finally
{
// Do nothing
}
return startClassThreadReturn;
}
Here is the output I receive from CruiseControl.NET, as opposed to testing within Visual Studio:
<message>Passed UnitTests.clsThreadTest.StartClassThreadTest2</message>
<message>Process 'QTAgent32' [PID 3932] has finished profiling.</message>
<message>Process 'QTAgent32' [PID 5388] has begun profiling.</message>
<message>Error UnitTests.clsUltraCalendarTest.clsUltraCalendarConstructorTest</message>
Does anyone have any ideas as to how I can resolve these errors? TIA.
UPDATE: Here is the full source code for clsThread.cs (please note that line 23 is objThreadMethod(); ):
namespace CommonObjects4
{
public class clsThread
{
#region '" Sub Class "'
public delegate void ThreadMethod();
private class StartThreadMethod
{
public ThreadMethod objThreadMethod;
public void Execute()
{
objThreadMethod(); // this is line 23
}
}
#endregion
#region '" Enumerator Declaration "'
#endregion
#region '" Variable Declaration "'
#endregion
#region '" Property Declaration "'
#endregion
#region '" Function Declaration "'
public Thread StartClassThread(Thread ThreadObject, ThreadMethod MethodObject)
{
System.Threading.Thread startClassThreadReturn = null;
try
{
if (ThreadObject == null && MethodObject == null)
{
throw new ApplicationException("Cannot have both ThreadObject and MethodObject as null parameters in call to StartClassThread.");
}
StartThreadMethod objMethod = new StartThreadMethod();
objMethod.objThreadMethod = MethodObject;
if (!(ThreadObject == null))
{
if (ThreadObject.ThreadState != System.Threading.ThreadState.Stopped)
{
// Do nothing
}
}
if (!(ThreadObject == null))
{
if (ThreadObject.ThreadState == System.Threading.ThreadState.Stopped | ThreadObject.ThreadState == System.Threading.ThreadState.Aborted )
{
ThreadObject = null;
ThreadObject = new Thread( new System.Threading.ThreadStart( objMethod.Execute ) );
ThreadObject.Start();
}
}
else
{
ThreadObject = new Thread( new System.Threading.ThreadStart( objMethod.Execute ) );
ThreadObject.Start();
}
return ThreadObject;
}
catch (Exception excException)
{
ZEGApp.clsMain.objApplicationAudit.AuditMethodError(excException, System.Reflection.MethodInfo.GetCurrentMethod().DeclaringType.FullName + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + " - " + excException.StackTrace);
}
finally
{
// Do nothing
}
return startClassThreadReturn;
}
#endregion
}
}
The problem would appear to be that
objThreadMethodis null at line 23. The syntaxobjThreadMethod()is actually shorthand forobjThreadMethod.Invoke(), so you’ll get aNullReferenceExceptionifobjThreadMethodis null when the line is executed.As for why it’s null, I’m guessing that you’ve invoked the
StartClassThreadmethod with a non-nullThreadObjectand a nullMethodObject, which resulted in the following block being executed after settingobjMethod.objThreadMethodto the nullMethodObject: