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论坛发了同样的问题

thread. join()在线程中传递最后一行后间歇性挂起

我在一些win10机器上的应用程序域卸载阻塞时也有类似的症状。我观察到,当进程退出日志显示代码后,应用程序域神奇地卸载。

我的解决方案:通过在cmd行中发送包含exec所需参数的json对象的文件路径,在专用进程中隔离实际的ranorex作业。

看起来ranorex应该为这混乱负责。它在目标进程中注入代码的事实并没有帮助…