Пошаговое руководство. Отладка многопоточного приложения с помощью окна Threads (C#, Visual Basic, C++)
Несколько элементов пользовательского интерфейса Visual Studio позволяют отлаживать многопоточные приложения. В этой статье представлены функции многопотоковой отладки в окне редактора кода, на панели инструментов Место отладки и в окне Потоки. Дополнительные сведения о других средствах отладки многопоточных приложений см. в разделе Начало отладки многопоточных приложений.
Выполнение этого учебника занимает всего несколько минут, в ходе которых вы ознакомитесь с основами отладки многопоточных приложений.
Создание проекта многопоточного приложения
Создайте следующий проект многопоточного приложения для использования в этом учебнике:
Откройте Visual Studio и создайте новый проект.
Если окно запуска не открыто, выберите Файл>Окно запуска.
В окне запуска выберите новый проект.
На начальном экране выберите Создать проект.
В поле поиска окна Создание проекта введите консоль. Затем выберите C# или C++ в списке языков и Windows в списке платформ.
После применения фильтров языка и платформы выберите консольное приложение для .NET Core, .NET 5+ или C++, а затем нажмите кнопку "Далее".
Примечание.
Если нужный шаблон проекта отсутствует, перейдите в меню Сервис>Получить средства и компоненты..., после чего запустится Visual Studio Installer. Выберите рабочую нагрузку Разработка классических приложений .NET или Разработка классических приложений на C++, а затем нажмите кнопку Изменить.
В окне Настроить новый проект введите имя в поле Имя проекта или оставьте имя по умолчанию. Затем щелкните Далее или Создать в зависимости от того, какой вариант доступен.
Для .NET Core или .NET 5+выберите рекомендуемую целевую платформу или .NET 8, а затем нажмите кнопку "Создать".
Появится новый проект консольного приложения. Когда проект будет создан, откроется файл исходного кода. В зависимости от выбранного языка исходный файл может вызываться Program.cs или MyThreadWalkthroughApp.cpp.
Замените код в исходном файле на пример кода C# или C++ из раздела Начало отладки многопоточных приложений.
Нажмите Файл>Сохранить все.
Запуск отладки
Найдите следующие строки в исходном коде:
Установите точку останова на строке
Console.WriteLine();
, щелкнув в левом поле или выбрав строку и нажав клавишу F9.Точка останова отображается как красный кружок в левом поле рядом со строкой кода.
Выберите Отладка>Начать отладку или нажмите клавишу F5.
Приложение запускается в режиме отладки и останавливается в точке останова.
В режиме приостановки откройте окно Потоки, выбрав Отладка>Windows>Потоки. Чтобы открыть или просмотреть окно Потоки и другие окна отладки, необходимо находиться в сеансе отладки.
Проверка маркеров потоков
В исходном коде найдите строку
Console.WriteLine();
.- Щелкните правой кнопкой мыши окно "Потоки" и выберите "Показать потоки" в меню "Источник".
Теперь рядом с строкой исходного кода отображается значок маркера потока. маркер потока указывает, что некий поток остановлен в этом месте. Если в расположении находится несколько остановленных потоков, появится значок.
Наведите указатель мыши на маркер потока. Подсказка сообщает имя и идентификационный номер каждого остановившегося тут потока. Имена потоков могут иметь значение
<No Name>
.Совет
Чтобы различать безымянные потоки, их можно переименовать в окне Потоки. Щелкните поток правой кнопкой мыши и выберите пункт Переименовать.
Щелкните маркер потока в исходном коде правой кнопкой мыши, чтобы просмотреть доступные параметры в контекстном меню.
Установка и снятие отметки для потоков
Вы можете помечать требующие внимания потоки, чтобы следить за ними.
Устанавливайте и снимайте метки потоков в редакторе исходного кода или в окне Потоки. Выберите, следует ли отображать только помеченные потоки или все потоки, в окне Место отладки или Потоки. Выбор, сделанный из любого расположения, влияет на все расположения.
Установка и снятие метки для потоков в исходном коде
Чтобы открыть панель инструментов Место отладки, выберите Вид>Панели инструментов>Место отладки. Можно также щелкнуть правой кнопкой мыши в области панели инструментов и выбрать Место отладки.
Панель инструментов "Расположение отладки" содержит три поля: "Процесс", "Поток" и "Кадр стека". Откройте раскрывающийся список Поток и обратите внимание на количество потоков. В списке Поток выполняющийся в данный момент поток помечается символом >.
В окне исходного кода наведите указатель мыши на значок маркера потока в поле и выберите значок флага (или один из пустых значков флагов) в подсказке. Значок флага становится красным.
Можно также щелкнуть правой кнопкой мыши значок маркера потока, навести курсор на Флаг, а затем выбрать поток для пометки в контекстном меню.
На панели инструментов "Расположение отладки" щелкните значок "Показать только помеченные потоки" справа от поля "Поток". Значок неактивен, если ни один поток не помечен.
Теперь в раскрывающемся списке Поток на панели инструментов отображается только помеченный поток. Нажмите кнопку Показывать только помеченные потоки еще раз, чтобы снова отображались все потоки.
Совет
Пометив несколько потоков, поместите курсор в редакторе кода, щелкните правой кнопкой мыши и выберите Запустить помеченные потоки до курсора. Обязательно выберите код, которого достигнут все потоки. Запустить помеченные потоки до курсора — потоки будут приостановлены в выбранной строке кода, что упрощает управление порядком выполнения путем замораживания и размораживания потоков.
Чтобы снять или установить метку текущего выполняющегося потока, выберите флаг Переключить состояние пометки текущего потока слева от кнопки Показывать только помеченные потоки. Помечать текущий поток удобно для поиска текущего потока, когда отображаются только помеченные потоки.
Чтобы снять метку с потока, наведите указатель мыши на маркер потока в исходном коде и выберите значок красного флажка, чтобы удалить его, или щелкните правой кнопкой мыши маркер потока и выберите Снять метку.
Установка и снятие меток для потоков в окне "Потоки"
В окне "Потоки" помеченные потоки имеют красные значки флага рядом с ними, а не отложенные потоки, если показано, имеют пустые значки контура.
Выберите значок флага, чтобы изменить состояние потока на "помечено" или "не помечено" в зависимости от его текущего состояния.
Можно также щелкнуть правой кнопкой мыши строку и выбрать Пометить, Снять метку или Снять метку для всех потоков из контекстного меню.
На панели инструментов в окне Потоки также есть кнопка Показывать только помеченные потоки (правая из двух значков с флагом). Она работает так же, как кнопка на панели инструментов Место отладки, и обе кнопки управляют отображением в обоих расположениях.
Другие функции окна "Потоки"
В окне Потоки выберите заголовок любого столбца, чтобы отсортировать потоки по этому столбцу. Щелкните еще раз, чтобы изменить порядок сортировки. Если отображаются все потоки, то при выборе столбца со значком флага выполняется сортировка потоков по наличию метки.
Вторым столбцом окна Потоки (без заголовка) является столбец Текущий поток. Желтая стрелка в этом столбце отмечает текущую точку выполнения.
В столбце Расположение показано, где каждый поток отображается в исходном коде. Щелкните стрелку "Развернуть" рядом с пунктом Расположение или наведите указатель мыши на пункт, чтобы отобразить частичный стек вызовов для этого потока.
Совет
Для графического представления стеков вызовов для потоков используйте окно Параллельные стеки. Чтобы открыть это окно, во время отладки выберите Отладка>Окна>Параллельные стеки.
Помимо пунктов Пометить, Снять меткуи Снять метку для всех потоков, в контекстном меню для окна Поток есть следующие элементы.
- Кнопка Показать потоки в исходном коде.
- Шестнадцатеричное отображение, которое изменяет идентификатор потока в окне Потоки с десятичного на шестнадцатеричный формат.
- Переключиться на поток — немедленное переключение на выполнение этого потока.
- Переименовать — изменение имени потока.
- Команды Замораживание и размораживание.
Замораживание и оттаивание выполнения потока
Вы можете замораживать и размораживать (приостанавливать и возобновлять) потоки для управления порядком их выполнения. Замораживание и размораживание потоков поможет устранить проблемы параллелизма, такие как взаимоблокировки и состояния гонки.
Совет
Для отслеживания одного потока без замораживания других потоков, что также является распространенным сценарием отладки, см. раздел Начало отладки многопоточных приложений.
Закрепление и снятие закрепления потоков:
В окне Потоки щелкните правой кнопкой мыши любой поток и нажмите Заморозить. Значок паузы в столбце Текущий поток указывает, что поток заморожен.
Выберите Столбцы на панели инструментов окна Потоки, а затем выберите Число приостановок, чтобы отобразить столбец Число приостановок. Значение числа приостановок для замороженного потока равно 1.
Щелкните правой кнопкой мыши замороженный поток и выберите Разморозить.
Значок паузы исчезает, а значение числа приостановок меняется на 0.
Переключение на другой поток
При попытке переключиться на другой поток может появиться окно Приложение находится в режиме приостановки выполнения. В этом окне сообщается, что у потока нет кода, который может быть отображен текущим отладчиком. Например, вы можете выполнять отладку управляемого кода, но поток является машинным кодом. В окне предлагаются решения этой проблемы.
Переключение на другой поток
В окне Потоки запишите идентификатор текущего потока, который выделен желтой стрелкой в столбце Текущий поток. Переключитесь обратно на этот поток, чтобы продолжить работу приложения.
Щелкните другой поток правой кнопкой мыши и выберите Переключиться на поток из контекстного меню.
Обратите внимание, что положение желтой стрелки в окне Потоки изменилось. Исходный маркер текущего потока также остается в виде контура.
Взгляните на подсказку маркера потока в редакторе исходного кода и список в раскрывающемся меню Поток на панели инструментов Место отладки. Обратите внимание, что указанный там текущий поток также изменился.
На панели инструментов Место отладки выберите другой поток из списка Поток. Обратите внимание, что текущий поток изменяется и в других двух расположениях.
В редакторе исходного кода щелкните правой кнопкой мыши маркер потока, наведите курсор на пункт Переключиться на поток и выберите другой поток из списка. Обратите внимание, что текущий поток изменяется во всех трех расположениях.
С помощью маркера потока в исходном коде можно переключаться только на потоки, остановленные в этом расположении. С помощью окна Потоки и панели инструментов Место отладки можно переключиться на любой поток.
Вы познакомились с основами отладки многопоточных приложений. Вы можете отслеживать, помечать и снимать метки, а также замораживать и размораживать потоки, используя окно Потоки, список Поток на панели инструментов Место отладки или маркеры потоков в редакторе исходного кода.