在 C# 中手动设置线程退出代码?

Posted

技术标签:

【中文标题】在 C# 中手动设置线程退出代码?【英文标题】:Set thread exit code manually in C#? 【发布时间】:2017-02-07 11:27:58 【问题描述】:

有没有办法在 C# 中手动设置线程退出代码(用于调试目的)?

相关问题“What is a thread exit code?”的选定答案指出:

0 往往意味着它安全退出,而其他任何东西往往意味着它没有按预期退出。但是这个退出代码可以自己在代码中设置,完全忽略这一点。

真的有办法自己设置线程的退出代码吗?

【问题讨论】:

你不应该在.net中使用/依赖它们,原因/解释here。 有一个 Windows API 调用 ExitThread(DWORD) 使用提供的退出代码退出线程。但我很确定从托管线程中调用它是一个非常糟糕的主意,因为 Manfred 链接的原因 【参考方案1】:

.NET 线程没有退出代码。这些由 Windows 上的本机线程使用,但本机线程仅由托管线程使用,并且与给定的托管线程没有 1:1 对应关系。同一个托管线程可以在多个本机线程上运行,反之亦然(尽管显然不能同时运行)。引用 MSDN:

操作系统 ThreadId 与托管线程没有固定关系,因为非托管主机可以控制托管线程和非托管线程之间的关系。具体来说,复杂的主机可以使用 Fiber API 针对同一个操作系统线程调度多个托管线程,或者在不同操作系统线程之间移动一个托管线程。

这当然适用于绑定到本机线程的所有资源 - 当然,运行时确实管理线程的托管资源;对于调用托管代码的非托管代码,线程将保持不变 - 否则互操作将是完全不可能的。

如果您想为任务添加额外信息,请尝试使用更高级别的抽象 - 例如Task。需要在完成时输出任务的状态?添加一个延续。需要检查您有参考的任务的状态?等待它或查询Task 对象。

【讨论】:

“同一个托管线程可以运行在多个本机线程上”,怎么会呢? @MathuSumMut 为什么不呢?它不以任何方式绑定到本机线程。运行时决定哪些本机线程处理哪些托管线程。 为什么托管线程不能与本地线程 1:1 绑定?这样做是为了保持互操作性。我知道您正在按照规范允许的技术上进行,但是不映射 1:1 没有任何好处,而且实际上,为了不与实现绑定,有一个单独的线程池用于那个。 @MathuSumMut 互操作性是一个不同的场景——在这种情况下,相同的本机线程保持绑定到托管线程。 通常保持 1:1 映射没有任何好处,并且在 MS SQL CLR 等类似场景中会严重限制运行时。不要忘记 .NET 相当雄心勃勃——他们不想对高度可扩展的系统和其他要求苛刻的场景关闭任何大门。 如何严格限制运行时间?

以上是关于在 C# 中手动设置线程退出代码?的主要内容,如果未能解决你的问题,请参考以下文章

C# 中 多线程同步退出方案 CancellationTokenSource

在 C# 应用程序退出时清理非托管 C++ 线程

线程以代码 0 (0x0) 退出,没有未处理的异常

c#关闭窗口怎么强制退出所有运行的线程

C#工程中输出类型转换以及程序运行后控制台窗口不退出设置

C# winForm Socket 多线程 编程 关闭问题