【问题标题】:detect when a new managed thread has been created检测何时创建了新的托管线程
【发布时间】:2011-10-09 08:30:57
【问题描述】:

有谁知道是否可以检测到在托管环境中何时创建了新线程?

我想要一份我的应用程序中所有线程的列表(每个线程的 ID 和名称)。我在 Visual Studio 中使用并发可视化工具,它只显示线程 ID(而不是线程名称)。如果您有 20 多个没有名称的线程,则很难将程序流程可视化。

编辑: 使用Process.GetCurrentProcess()。线程不行,因为 CLR 不保证托管线程和非托管线程之间的一对一映射。

一种解决方案是创建某种线程管理器,所有线程创建都必须通过它来完成。它还将管理所有当前活动线程的列表。

【问题讨论】:

  • 为什么? (您要解决的真正问题是什么)
  • 您的Process 对象将包含所有线程的列表。这就是你所需要的吗?如果您真的想在创建新线程时收到通知,您可能必须使用调试/分析接口。
  • 这需要调试器。程序无法自行调试。无论您要解决什么问题,这都不是解决问题的正确方法。
  • 我已经在上面详细解释了我的问题。

标签: c# .net


【解决方案1】:

答案是否定的,你不能——你甚至不能枚举所有当前的“托管”线程,更不用说在创建/销毁线程时得到通知了。

How can I enumerate all managed threads in C#?

注意:您可以使用Process 类枚举进程中的所有线程:

Process.GetCurrentProcess().Threads

这不会告诉您其中哪些是“托管的”,并且不会在创建或销毁线程时通知您。

您可以通过查看托管线程的堆栈跟踪来尝试找出哪些线程是“托管”的,但老实说,我不知道这是否真的适用于非托管线程,这一切都开始看起来真的狡猾!

new StackTrace().GetFrame(someThread)

澄清一下 - 你几乎肯定不应该做这些,这只是一些背景。

【讨论】:

  • 使用 Process.GetCurrentProcess().Threads 不行,因为 CLR 不保证托管线程和非托管线程之间的一对一映射。
  • Zvonko 一对一映射是什么意思?如果您的意思是 Threads 集合可能包含非托管线程,那么它几乎肯定会包含。
  • 操作系统 ThreadId 与托管线程没有固定关系,因为非托管主机可以控制托管线程和非托管线程之间的关系。具体来说,复杂的主机可以使用 Fiber API 针对同一个操作系统线程调度许多托管线程,或者在不同操作系统线程之间移动托管线程。见msdn.microsoft.com/en-us/library/74169f59.aspx
【解决方案2】:

一种解决方案是在创建线程时将它们存储在Queue 中,并定期检查Queue 的内容。虽然不是一个完美的解决方案。

【讨论】:

  • 这个解决方案意味着你控制几乎不是这种情况的每个线程(例如:ThreadPool)。
  • @Julien 好吧,这取决于您要监视的线程。如果您只需要管理已明确创建的线程,它就可以工作。
  • List 是一个更好的选择,恕我直言。但是,在此解决方案中,您必须创建自己的“线程管理器”,放弃直接创建线程和使用 ThreadPool,在线程管理器中为两者创建包装器并严格使用这些包装器。
猜你喜欢
  • 1970-01-01
  • 2010-11-16
  • 2011-07-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-17
  • 2014-04-21
  • 2014-12-21
相关资源
最近更新 更多