thread. join()在线程中传递最后一行后间歇性挂起
本文关键字:一行 挂起 join 线程 thread 最后 | 更新日期: 2023-09-27 18:01:58
我有一个控制台。net应用程序,用于执行测试自动化。
应用程序从主线程中调用一个单独的线程,并在该新线程中执行自动脚本-如下所示:
void runScriptSeparateThread(TestScript script)
{
// do some stuff
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");
}
// do some other stuff
}
void executeScript(TestScript script)
{
// run test script using reflection calls to external assemblies
// includes invocation of new threads which will live after this thread finishes
// can potentially include any calls - according to needs of test automation
File.AppendAllText(@"C:'log.txt", "Message inner");
}
问题是:有时,在方法executeScript()
到达其线程中的最后一行后,主线程中的方法.Join()
继续等待超时。也就是说,文本"Message inner"
存在于"C:'log.txt"
文件中,但文本"Message outer"
缺失。
NB:上面描述的行为在executeScript()
方法开始生成具有STA公寓状态的新线程时间歇性地再现。新的线程使用Ranorex工具执行UI控件的监控——这些工具在后台执行我不熟悉的Win32 API调用。所有新线程的引用都被传递给主线程,并且假定在executeScript()
方法的线程存在之后仍然存在。
方法executeScript
根据自动脚本使用反射进行调用-并且可以潜在地执行任何可以在系统上使用。net实现的调用。
我的问题是:是否有可能调用新线程阻塞executeScript()
方法在单独线程中的执行-即使在方法到达最后一行之后?是否可能是线程的STA公寓状态和一些Win32调用导致消息泵送是线程的函数通过所有行后挂.Join()
方法的原因?
注意: .Join()
方法的悬挂很少发生,仅在实验室机器上重现。我没有设法在本地机器上重现行为-即使在一夜之间自动执行了数百次。
找到的解决方案:到目前为止,我已经结束了以下的解决方案-诉诸ManualResetEventSlim
的使用等待线程的完成,如下所示:
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();
}
在MSDN论坛发了同样的问题
我在一些win10机器上的应用程序域卸载阻塞时也有类似的症状。我观察到,当进程退出日志显示代码后,应用程序域神奇地卸载。
我的解决方案:通过在cmd行中发送包含exec所需参数的json对象的文件路径,在专用进程中隔离实际的ranorex作业。
看起来ranorex应该为这混乱负责。它在目标进程中注入代码的事实并没有帮助…