确定线程的来源

时间:2009-05-06 16:13:38

标签: c# .net multithreading debugging

我在一个小应用程序中遇到了高度的闪烁和UI延迟,我开发这个应用程序来测试我为我们的某个应用程序编写的组件。因为在空闲时间(当应该 - 严重 - 没有任何事情发生)时发生闪烁和滞后,我决定做一些调查。我注意到Threads窗口中有一些我不知道的线程(并非完全出乎意料),但引起我注意的是其中一个线程设置为Highest优先级。即使在我的任何代码执行之前,此线程在调用Main()时也存在。我发现这个线程似乎存在于我编写的每个.NET应用程序中,甚至是控制台应用程序。

作为我的大胆灵魂,我决定冻结线程,看看发生了什么。闪烁确实停止了,但是在进行数据库交互时我遇到了一些奇怪的问题(我使用的是SQL CE 3.5 SP1)。我的想法是,这可能是数据库实际运行的线程,但考虑到它是在应用程序加载时(在对数据库的任何引用之前)启动并且存在于其他非数据库应用程序中,我倾向于相信情况并非如此。

因为这个线程(就像其他几个)在Location列中没有数据而且在暂停时我在调试器中切换到它时没有列出Call Stack,所以我尝试通过GetCurrentProcess()匹配StartAddress属性。相应的线程,但它超出了所有当前加载的模块地址范围。

有没有人知道这个帖子是什么,或者我怎么知道?

修改

在进行一些挖掘后,看起来StartAddress位于kernel32.dll中(基于附近的内存内容)。这导致我认为这只是用于启动线程的标准系统函数,根据this page,这基本上使我回到正方形,直到确定该线程实际来自何处。这一事实进一步证实了这个列表中的所有线程都具有相同的StartAddress值,这使我确切地询问其目的是什么......?

修改2

Process Explorer让我得到一个实际有意义的起始地址。它看起来像是mscorwks.dll!CreateApplicationContext+0xbbef。这个DLL在%WINDOWS%\ Microsoft.NET \ Framework \ v2.0.50中,所以看起来它显然是一个运行时程序集。我还不确定为什么

  • 这是最高优先级
  • 它似乎在我的应用程序中造成打嗝

3 个答案:

答案 0 :(得分:6)

您可以尝试使用SysinternalsProcess Explorer让你深入挖掘。右键单击Process以访问Properties。然后“线程”选项卡。在那里,你可以看到线程的堆栈和模块。

编辑:

在{{}}之后,似乎你的“最高”优先级线程是由于垃圾收集而运行的Finalizer线程。我仍然没有充分的理由知道它为什么会一直运行。也许你的过程中会有一些时髦的对象终身行为?

答案 1 :(得分:2)

我不确定这是什么,但是如果你打开非托管调试,并使用Windows symbol server设置Visual Studio,你可能会得到更多线索。

答案 2 :(得分:0)

可能是垃圾收集器线程。当我一次调查与终结者有关的错误时,我也注意到了这一点。也许您的系统内存很低,GC正在尝试一直收集?这也是前面提到过的bug的情况。我无法在我的机器上重现它,但是我的一个同事有一台内存较少的机器,它会像发条一样重新出现。