Как отлаживать один поток в Visual Studio?

У меня есть решение с некоторыми проектами. В разных проектах есть несколько точек разрыва. Я хочу, чтобы первый поток попал в одну из этих точек останова и продолжал отслеживать этот единственный поток, несмотря на то, что другие потоки входили в одни и те же кодовые блоки.

Я знаю, что это возможно, определяя условие на точке прерывания, то есть имя потока =... или поток Id =... но мой случай - это тяжелая загруженная ASP.NET, и как только я присоединюсь к w3wp.exe, многие потоки попадут в точки останова. Мне нужно что-то вроде ThreadLocal<break-point>.

Возможно ли это? Если да, то как?

Ответ 1

Потоки замораживания/отталкивания являются неправильным способом, поскольку другие потоки не выполняют никакого кода.

Самый правильный и полезный способ:

  • Нажмите Ctrl + A в окне точек останова (выберите все точки останова).
  • Щелкните правой кнопкой мыши и выберите "Фильтр...".
  • Введите "ThreadId = (текущий поток id)".

В Visual Studio 2015 и новее процесс похож:

  • Нажмите Ctrl + A в окне точек останова (выберите все точки останова).
  • Щелкните правой кнопкой мыши и выберите "Настройки...".
  • Проверьте "Условия" и выберите "Фильтр" в раскрывающемся меню
  • Введите "ThreadId = (текущий поток id)".

Итак, все потоки выполняются, но отладчик ударяет только по текущему потоку.

Ответ 2

Вот что я сделал:

  • Установите условную точку прерывания, чтобы я   знал бы, только ударил по нитке   что я искал.

  • Как только точка останова попадет в нужный вам поток, в окне "Темы Visual Studio" (при отладке, "Отладка" → "Windows → Темы" ), Ctrl + A (чтобы выбрать все потоки), а затем Ctrl + щелкните поток, в котором вы сейчас находитесь. У вас должны быть все потоки, кроме тех, которые вы хотите отлаживать.

  • Щелкните правой кнопкой мыши и выберите "Заморозить".

Теперь Visual Studio будет только проходить через оттаиваемый поток. Похоже, что это происходит намного медленнее, по-видимому, потому, что ему нужно перебирать все замороженные потоки, но это привнесло некоторую здравомыслие в мою многопоточную отладку.

Ответ 3

Я только что выпустил расширение Visual Studio 2010+, которое делает именно то, что вы ищете. И это бесплатно :).

Presentation

Это расширение Visual Studio добавляет два ярлыка и кнопки на панели инструментов, чтобы разработчики могли легко сосредоточиться на отдельных потоках при отладке многопоточных приложений.

Это значительно снижает необходимость вручную заходить в окно "Потоки", чтобы заморозить/разморозить все потоки, кроме того, которое необходимо соблюдать, и, следовательно, помогает повысить производительность.

Features

Ограничить дальнейшее выполнение только текущим потоком. Заморозит все остальные темы. Сочетание клавиш: CTRL + T + T или кнопка Снежинка. Перейти к следующему отдельному потоку (на основе идентификатора). Изменит текущую тему и заморозит все остальные темы. Сочетание клавиш: CTRL + T + J или следующая кнопка.

Проверьте это здесь, в галерее, на официальной странице или в репозитории Github.

Ответ 4

Если несколько потоков генерируются как для веб-приложения, ответ @MattFaus не будет работать. вместо этого я сделал следующее

  • Настройте точку останова, чтобы прервать поток в функции, которую я хочу.
  • Как только поток попадает в точку останова и приостанавливается, я удаляю точку останова и продолжаю отладку с помощью F8, F10 и F11, так что остальные потоки могут запускаться.

Ответ 5

Несколько иной подход, который я использовал:

  • Создайте нормальную точку останова и пусть она попадет
  • Посмотрите в окне ваших потоков идентификатор управляемого потока, который вы используете для текущей отладки
  • Щелкните правой кнопкой мыши точку останова в окне точек останова и выберите фильтр
  • Введите ThreadId = xxx, где xxx - это идентификатор потока из 2
  • Теперь вы можете отлаживать, не останавливая другие потоки, и без их удара по точке останова.

Предполагается, что у вас есть время, чтобы сделать это, прежде чем второй поток попадет в точку останова. Если это не так, и другие потоки попали в точку останова до того, как вы сделали это, вы можете щелкнуть их правой кнопкой мыши в окне потоков и выбрать "заморозить".

Ответ 6

Я бы предложил добавить еще один экземпляр приложения на реальном сервере, либо на том же оборудовании, либо на новом компьютере (кластер), а затем отлаживать только этот экземпляр. Я бы не добавил точку останова в загрузке кода. Если это не вариант, я бы добавил больше трассировки.

Однако, если это абсолютно необходимо, и вам нужен stat решения, я уверен, вы можете добавить точку останова, которая ломается, только если запрос поступает с вашего IP-адреса. Вы сделали бы это, добавив условную точку останова, которая проверит HttpContext.Request.UserHostAddress. Обратите внимание, что это значительно замедляет ваше приложение.

Ответ 7

Если вы не хотите останавливать все остальные потоки (возможно, вы прикрепляете отладчик Visual Studio к запущенному приложению, которое должно отвечать на запросы), вы можете использовать макрос, который автоматически создает и удаляет точки останова.

В предлагается ответ на вопрос "Переполнение стека" при отладке многопоточных программ в Visual Studio.

Однако ссылка только объясняет, как отлаживать строку за строкой. Я предлагаю вам изменить макрос (если вам удобно с ним), чтобы он изменял все точки останова (в данном диапазоне строк, например), чтобы останавливаться только на текущем потоке.

Ответ 8

Я думаю, что это немного отличается в Visual Studio 2015. Они изменили несколько вещей в точках прерывания, но здесь, как применить принятый ответ от hzdbyte (выше):

В точке останова в поле кодирования щелкните правой кнопкой мыши > Условия > Изменить с "Условное выражение" на "Фильтр". Затем вы можете фильтровать ThreadId.

В качестве альтернативы в точке останова в окне "Точки останова" щелкните правой кнопкой мыши > "Настройки" > отметьте поле "Условия" и выполните указанные выше действия.

Ответ 9

Установите условие точки останова, щелкнув правой кнопкой мыши на боковой панели линии. Выберите "Условие" и введите в кавычки следующее имя:

System.Threading.Thread.CurrentThread.Name == "name_of_your_thread"

В качестве альтернативы вы можете сделать то же самое, получив поток "Управляемый идентификатор" из окна "Потоки" и используя:

System.Threading.Thread.CurrentThread.ManagedThreadId == your_managed_thread_id