.Net Profiling - 了解托管线程的开始和结束

Posted

技术标签:

【中文标题】.Net Profiling - 了解托管线程的开始和结束【英文标题】:.Net Profiling - Knowing the managed thread begin and end 【发布时间】:2014-10-31 09:09:30 【问题描述】:

我正在开发一个 .Net 分析器。我为此使用 ILRewriting。

我需要跟踪托管线程的创建和销毁。

需要知道将在线程开始和线程结束期间调用的线程相关函数,我可以将我的代码注入其中并在事件发生时记录。

关于将在线程创建和结束时调用的默认函数的任何想法..??

或者还有其他方法可以捕获托管线程的创建和销毁事件吗?

我知道我们可以通过设置线程事件掩码进行跟踪..但我需要捕获特定的托管线程而不是所有线程..

【问题讨论】:

你不使用 IL 重写来编写分析器。您使用 CLR 的内置支持进行分析。 ICorProfilerCallback::ThreadCreated() 和 ThreadDestroyed 告诉你你需要什么。 没关系@HansPassant ..但是即使在页面加载完成之后主线程(为页面加载而启动)也没有被破坏,(即)即使在调用unloadrecursive之后......我不知道它有什么问题。 还有一件事.. 据我所读,我知道ThreadID 来自探查器 dll 中的ThreadCreated 函数是一个 ManagedThreadID .. 但是对于同一个线程,如果我得到在 C# 代码中,ManagedThreadID 是其他一些数字,例如。 10 或 11 。使用 CurrentThread.ManagedThreadID 。那么这里是托管线程ID.. ??我完全糊涂了.. 【参考方案1】:

正如 Hans 指出的,CLR 使用 ThreadCreated 和 ThreadDestroyed 回调通知分析器线程创建/销毁。注意:如果运行时在线程终止之前关闭,那么您将不会获得 ThreadDestroyed 回调......但我认为您没有获得 ThreadDestroyed 回调的更可能原因是 IIS(我假设“页面加载”您指的是 asp .NET 页面)决定保留线程以供将来的请求作为优化,如果它认为它有足够的其他线程,它可能会决定稍后终止它。

另外,关于您对该问题的第二条评论,ThreadID 和ManagedThreadID 之间没有关系。我相信 ThreadID 是对内部数据结构的引用(将其视为不透明的值,不要试图解释它),并且 ManagedThreadID 似乎是一个简单的数字,当线程首先进入托管代码时顺序分配。如果您想确定哪个 ThreadID 对应于哪个托管线程,我可以想到 3 个选项:

使用ThreadNameChanged回调检查线程名称(注意:如果线程名称是在线程启动之前设置的,那么这将在ThreadCreated回调之前引发) 使用ThreadAssignedToOSThread 回调检查操作系统线程ID 将分析代码调用到分析器中,为其提供上下文(使用 pinvoke 或调用为此目的而检测的方法)

【讨论】:

以上是关于.Net Profiling - 了解托管线程的开始和结束的主要内容,如果未能解决你的问题,请参考以下文章

通过 CLI 包装器在非托管 C++ 中使用 C#.NET Winform - 需要线程?

vb.net 线程托管 窗口假死

作为 .Net 攻城师,所必需掌握的 .Net Profiling 技术

了解 GoLang Profiling 输出

为啥将托管 .NET 客户端设置为使用 STA 线程会导致本机 COM 服务器中出现异常问题?

.Net Profiling API 方法