I have written a unit test for an asynchronous class member. The test passes as expected when I execute my test under "Debug build". However, it hangs the CPU (while loop is deadlocked) when I execute my test under "Release build".
If I specifically configure the Unit test project with Debug build (that is Debug build unit test assembly and Release build target assembly), the test passes as well.
Code to Test
public override void DoSomething(object parameter)
{
ThreadPool.QueueUserWorkItem(AsyncDoSomething, parameter);
}
private void AsyncDoSomething(object parameter)
{
//Doing something
.....
//Something is done
RaiseSomethingIsDone();
}
My Unit Test
public void DoingSomethingTest()
{
bool IsSomethingDone = false;
//Setup
//Doing some setup here.
target.SomethingDone += (sender, args) =>
{
IsSomethingDone = true;
};
//Exercise
target.DoSomething(_someParameter);
while (!IsSomethingDone ){}
//Verify
//Doing some asserts here.
}
Here is the IL generated by the C# compiler under Debug configuration and Release configuration:
Debug while loop IL interpenetration:
IL_00cb: ldloc.s 'CS$<>8__locals7'
IL_00cd: ldfld bool IsSomethingDone
IL_00d2: ldc.i4.0
IL_00d3: ceq
IL_00d5: stloc.s CS$4$0001
IL_00d7: ldloc.s CS$4$0001
IL_00d9: brtrue.s IL_00c9
Release while loop IL interpenetration:
IL_00bc: ldloc.s 'CS$<>8__locals7'
IL_00be: ldfld bool IsSomethingDone
IL_00c3: brfalse.s IL_00bc
I understand there are better ways to synchronize the test thread to the background ThreadPool thread.
My questions are
why is the release build not working? The flag IsSomethingDone is not set by the worker thread.
Is it because the eventhandler (the lambda expression) does not get executed?
Is the event not raised correctly?
By the way, I verified that DoSomething is executed correctly and generated the correct result.
Follow up Questions:
Should one build unit test projects under Debug Build or Release Build ?
Should one test the target assembly under Debug Build or Release Build ?