2 回答
TA贡献1820条经验 获得超10个赞
这是一个令人惊讶的行为,但这是可以解释的。
首先,您必须知道进程的生命周期与主线程(又名主线程)的生命周期相关。我以为那是 Windows 的东西,但根据 Raymon Chen 的说法,这是 C 的东西。
无论如何,底线是:.NET 运行时必须保持主线程处于活动状态。
那么当你退出Main程序的方法时会发生什么?按照约定,.NET 运行时必须等待任何未标记为后台的线程。它在RunMainPost方法中这样做,而该方法又会调用WaitForOtherThreads. 这解释了为什么Thread.Join在所有前台线程完成其工作之前调用主线程不会成功。
但是,为什么mainThread.IsAlive返回 false 呢?
首先,您必须知道它IsAlive不直接绑定到线程。相反,它调用ThreadIsRunning. 如果底层线程没有死并且没有用TS_ReportDeador标记TS_Dead(这是因为运行时在线程向托管代码报告死后保持一段时间,以进行一些簿记/整理),这将返回 true 。
回到WaitForOtherThreads,如果您检查代码,您可以看到:
if (!OtherThreadsComplete())
{
TSLockHolder.Release();
FastInterlockOr((ULONG *) &pCurThread->m_State, Thread::TS_ReportDead);
DWORD ret = WAIT_OBJECT_0;
while (CLREventWaitWithTry(&m_TerminationEvent, INFINITE, TRUE, &ret))
{
}
_ASSERTE(ret == WAIT_OBJECT_0);
}
在m_TerminationEvent由最后一个线程终止设置。但重要的一点是FastInterlockOr((ULONG *) &pCurThread->m_State, Thread::TS_ReportDead);:主线程在等待其他线程之前将自己标记为死。它解释了为什么IsAlive是假的。
我已经通过构建 .NET Core 的自定义版本并注释掉该行来确认该假设。之后,IsAlive报道属实。
为什么要这样做?我只能猜测,但我认为这只是为了使运行时代码更简单。通过将主线程标记为死亡,其他实际死亡的线程可以检查(在上述簿记代码中)是否所有其他线程都死亡,并在这种情况下设置m_TerminationEvent. 这比检查“除了一个线程之外所有其他线程都死了”要稍微优雅一些。不过只是猜测。
- 2 回答
- 0 关注
- 197 浏览
添加回答
举报