gpt4 book ai didi

c# - 来自外部进程的 C# 中的线程问题

转载 作者:太空狗 更新时间:2023-10-29 23:34:41 24 4
gpt4 key购买 nike

我有这个简单的代码:

public void Run()
{
var invokerThread = new Thread(new ThreadStart(RunOnBackground));
invokerThread.Start();
}

private void RunOnBackground()
{
Trace.WriteLine("hi");
...
}

不幸的是,当运行此代码(来自第三方进程)时,线程并没有真正运行。在进程资源管理器和 VS 调试器中,我看到线程已创建且其状态为“正在运行”。

主线程的单元是 STA,我在内线程上尝试了 STA 和 MTA。

当我在 invokerThread.Join(); 末尾添加到 Run() 方法时,线程就会运行。但话又说回来,它并没有真正的帮助。

我错过了什么?

编辑:这里有一些关于代码托管的更多信息-

Run() 方法是通过 COM 互操作从一个进程调用的,该进程也是托管的可执行程序集(使用 COM 互操作的原因是因为系统中的所有其他组件都是 native 的)。

RunOnBackground() 方法在跟踪之后包含更多代码,通常其执行持续 10 到 20 秒,包括启动另一个进程和等待其终止。我在代码中还有一些其他区域,我将一些调试信息写入 Trace。在调试代码时,Run() 照常运行,并且在 invokerThread.Start(); 之后 invokerThread 的状态为“Running”(尽管 RunOnBackground() 中的断点 方法不要停止)。

当我在 Run() 方法末尾添加 invokerThread.Join() 时,调试器会转到 RunOnBackground() Join() 之后。

最佳答案

关于 RunOnBackground() 真正 的作用,缺少一些重要信息。这与在工作线程上使用单元线程 COM 对象时发生的情况非常匹配。 COM 自动将对此类对象的任何方法调用从工作线程编码到创建它的 STA 线程。

只有当 STA 线程遵守 STA 线程要求时,这才能很好地工作。它必须泵出一个消息循环并且不能阻塞。打破这些规则很可能会导致死锁,工作线程调用无法完成,直到 STA 线程调度编码调用。 Thread.Join() 解决了问题,这就是正在发生的事情的一个明确迹象。当在 STA 线程上调用时,它会在 CLR 内部泵送消息循环。

要对此进行诊断,您将需要 Debug + Windows + Threads 来查看工作线程阻塞了什么。如果我的猜测是正确的,它将深埋在 COM 管道代码中,等待编码调用完成。您只能通过启用非托管代码调试和设置 Microsoft 符号服务器来查看这一点,以便获得管道代码的调试符号并获得可靠的堆栈跟踪。

解决这个问题会很困难。当代码明确声明它不支持多线程时,您不能神奇地拨动开关并使代码在线程上运行。必须在调用其方法的同一线程上创建 COM 对象的实例。该线程必须是 STA 线程。检查这个sample code对于方法。如果您不控制 COM 对象的创建,那么您就会陷入困境。

关于c# - 来自外部进程的 C# 中的线程问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4422859/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com