I have console .NET application that performs execution of test automation.
Application's main thread has apartments state STA.
From the main thread application invokes new thread with STA apartment state to perform test automation - as follows:
void runScriptSeparateThread(TestScript script) { Thread runScriptThread = new Thread(() => executeScript(script)); runScriptThread.SetApartmentState(ApartmentState.STA); runScriptThread.Start(); if (runScriptThread.Join(timeout) == false) { runScriptThread.Abort(); File.AppendAllText(@"C:\log.txt", "Error: timeout "); } else { File.AppendAllText(@"C:\log.txt", "Message outer"); } } void executeScript(TestScript script) { // run test automation File.AppendAllText(@"C:\log.txt", "Message inner"); }
Problem is: Some times, after method executeScript() reaches its final line in its thread - method.Join() in the main thread continues to wait for timeout. That is - text"Message inner" is present in "C:\log.txt" file, but text"Message outer" is missing.
Note: Behavior described above reproduces intermittently for cases when at the beginning ofexecuteScript() method number of new threads is spawned with STA apartment state. New threads perform monitoring of UI controls withRanorex API. Ranorex performsWin32 API calls that I'm unfamiliar with. References of new threads are passed to main thread and supposed to live after thread ofexecuteScript() method exits.
Method executeScript() makes calls with reflection according to automated script - and can potentially do any calls that can be implemented in .NET on the platform.
My question is: Is it possible that invocation of new threads causes hanging of.Join() method for thread of executeScript() function? Can it be thatSTA apartment state of the thread and Win32 calls which manipulate UI and cause message pumping - result into hanging of.Join() method after all lines of the thread are executed?
Workaround used: To eliminate hanging of application I have ended up so far with a work around. For now I useManualResetEventSlim class to figure out when thread reaches its last call - as follows:
private ManualResetEventSlim executionControl = new ManualResetEventSlim(); private void runScriptSeparateThread(TestScript script) { this.executionControl.Reset(); Thread runScriptThread = new Thread(() => executeScript(script)); runScriptThread.SetApartmentState(ApartmentState.STA); runScriptThread.Start(); if (this.executionControl.Wait(timeout)) { runScriptThread.Abort(); File.AppendAllText(@"C:\log.txt", "Message outer"); } else { File.AppendAllText(@"C:\log.txt", "Error: timeout "); } } void executeScript(TestScript script) { // execute test automation File.AppendAllText(@"C:\log.txt", "Message inner"); this.executionControl.Set(); }Question was previously asked by me on stackoverflow forum here.