如何在Visual Studio中调试单个线程?

Xaq*_*ron 240 c# asp.net multithreading breakpoints visual-studio-2010

我有一些项目的解决方案.不同的项目有几个突破点.我想跟踪第一个线程命中其中一个断点并继续跟踪该单个线程,尽管其他线程进入相同的代码块.

我知道这可以通过在断点上定义条件来实现,也就是说,线程名称= ...或者线程ID = ...但我的情况是一个负载很重的ASP.NET应用程序,并且只要我附加到w3wp.exe许多线程将达到突破点.我需要一些像a ThreadLocal<break-point>.

可能吗?如果是这样,怎么样?

Mat*_*aus 321

这是我做的:

  1. 设置一个条件断点,我知道这个断点只会出现在我正在寻找的线程上.

  2. 一旦断点命中并且你在你想要的线程中,在Visual Studio线程窗口中(在调试,调试 - > Windows - >线程时),Ctrl+ A(选择所有线程),然后Ctrl+单击您当前所在的线程.除了要调试的线程之外,您应该拥有所有线程.

  3. 单击鼠标右键,然后选择"冻结".

现在,Visual Studio将只通过解冻的线程.这样做似乎要慢得多,大概是因为它必须循环遍历所有冻结的线程,但它为我的多线程调试带来了一些理智.

  • @Diego:我不再处理这个项目,但是如果要冻结除了一个之外的所有线程,它将改变导致该bug的场景,因为线程在错误情况下是互补的.虽然这是一个优雅的解决方案,但似乎这个功能应该嵌入到VS中. (3认同)
  • @ Meta-Knight您应该冻结所有线程**除外**主线程。如果您愿意的话,此IDE将不会冻结 (3认同)

小智 145

冻结/解冻线程是一种不正确的方式,因为其他线程不执行任何代码.

最正确和最有用的方法是:

  1. 在断点窗口中按Ctrl + A(选择所有断点).
  2. 右键单击并选择"过滤器...".
  3. 输入"ThreadId =(当前线程ID)".

Visual Studio 2015及更高版本中,过程类似于:

  1. 在断点窗口中按Ctrl + A(选择所有断点).
  2. 右键单击并选择"设置...".
  3. 选中"条件",然后在下拉列表中选择"过滤器"
  4. 输入"ThreadId =(当前线程ID)".

所以所有线程都被执行,但调试器仅在当前线程上命中.

  • 这是否会阻止"Step"调试器命令进入其他线程?这是我遇到的一个大问题.我正在逐步完成我的线程,突然之间,我处于一个完全不相关的代码部分.我不再在Visual Studio中开发,所以我无法测试. (43认同)
  • 在断点窗口中右键单击没有"过滤器"命令...你怎么知道当前的线程ID? - 您是否要进入即时窗口并键入`System.Threading.Thread.CurrentThread.ManagedThreadId`或其他内容? (6认同)
  • -1因为这只允许断点,但不允许实际调试:step over/step into不能以这种方式调试单个线程. (6认同)
  • 在我的VS(2015,Community Edition)中,无法一次修改多个断点的设置.因此,过滤器只能一个接一个地设置. (5认同)
  • 这在 VS2019 中不起作用,因为选择多个断点时设置会显示为灰色。 (5认同)
  • 我已经永远遇到了这个问题,我可以发誓,在我的上一份工作中,我发现了一个设置,让视觉工作室像eclipse一样工作,你坚持使用你正在使用的线程,但我找不到它或任何参考它.我开始怀疑自己是否梦见过它. (4认同)
  • 这个答案与提出的问题无关。它不仅让您调试单个线程,而且还展示了如何在单个线程上中断。 (3认同)
  • 尽管这个答案也很有用,但说冻结/解冻技术在所有情况下都是不正确的,这是不公平的,但在许多情况下,它更方便。 (2认同)

Erw*_*yer 14

我刚刚发布了一个Visual Studio 2010+扩展,它正是您正在寻找的.它是免费的:).

介绍

此Visual Studio扩展添加了两个快捷方式和工具栏按钮,使开发人员可以在调试多线程应用程序时轻松专注于单个线程.

它大大减少了手动进入"线程"窗口以冻结/解冻所有线程但需要遵循的线程的需要,因此有助于提高生产率.

特征

仅限进一步执行当前线程.将冻结所有其他线程.快捷方式:CTRL + T + T或雪花按钮.切换到下一个单线程(基于ID).将更改当前线程并冻结所有其他线程.快捷方式:CTRL + T + J或下一步按钮.

检查它在这里的画廊中,在官方网页Github上库.

  • 我要检查一下。您可能是地球上唯一尝试解决Microsoft最大的调试故障之一的人。 (2认同)

Mik*_*yer 11

如果正在为Web应用程序生成多个线程,则@MattFaus答案将不起作用.我做的是以下

  • 设置一个断点来中断我想要的函数中的线程.
  • 一旦线程到达断点并暂停,我将删除断点并继续使用F8,F10和F11进行调试,以便其他线程可以运行.


Mat*_*att 8

一个略有不同的做法,我使用:

  1. 创建一个普通断点并让它受到攻击
  2. 在您的线程窗口中查找您当前正在调试的托管线程ID
  3. 在断点窗口和选择器过滤器中右键单击断点
  4. 输入ThreadId = xxx,其中xxx是2的线程ID
  5. 您现在可以在不停止其他线程的情况下进行调试,并且不会让它们遇到断点

这假设您有时间在第二个线程到达断点之前执行上述操作.如果没有,其他线程在您完成上述操作之前点击了断点,您可以在线程窗口中右键单击它们并选择冻结.

  • +1."假设你有时间......在第二个线程到达你的断点之前".我将一个分号包在一个锁中,并在分号上加一个断点.当第一次触发断点时,我禁用断点.由于锁定,没有其他线程可以进入.`lock(m_someObject){; }` (2认同)