Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Visual Studio предоставляет несколько средств и элементов пользовательского интерфейса для отладки многопоточных приложений. В этом руководстве показано, как использовать маркеры потоков, окно Параллельных стеков , окно параллельных контрольных точек, условные точки останова и точки останова фильтра. В этом руководстве описаны функции Visual Studio для отладки многопоточных приложений.
В этих двух статьях содержатся дополнительные сведения об использовании других многопоточных средств отладки:
Чтобы использовать панель инструментов "Расположение отладки " и окно "Потоки ", см. пошаговое руководство. Отладка многопоточного приложения.
Пример, использующий Task (управляемый код) и среду выполнения параллелизма (C++), см. в пошаговом руководстве. Отладка параллельного приложения. Общие советы по отладке, применяемые к большинству многопоточных типов приложений, см. как в этой статье, так и в этой статье.
Первым шагом является создание многопоточного проекта приложения.
Создание многопоточного проекта приложения
Откройте Visual Studio и создайте проект.
Если окно запуска не открыто, выберите Файл>Окно запуска.
В окне запуска выберите Создать проект.
В окне Создание нового проекта введите консоль в поле поиска. Затем выберите C#, C++или Visual Basic в списке языков, а затем выберите Windows из списка платформ.
После применения фильтров языка и платформы выберите шаблон консольного приложения для .NET или C++, а затем нажмите кнопку "Далее".
Замечание
Если вы не видите правильный шаблон, перейдите к разделу "Сервис>получения инструментов и компонентов", который открывает установщик Visual Studio. Выберите компоненты разработки для .NET Desktop или разработки для Desktop с использованием C++, затем нажмите Изменить.
В окне "Настройка нового проекта " введите или введите MyThreadWalkthroughApp в поле "Имя проекта ". Затем нажмите кнопку "Далее " или "Создать", независимо от того, какой параметр доступен.
Для проекта .NET Core или .NET 5+ выберите рекомендуемую целевую платформу или .NET 8, а затем нажмите кнопку "Создать".
Появится новый проект консоли. После создания проекта появится исходный файл. В зависимости от выбранного языка исходный файл может вызываться Program.cs, MyThreadWalkthroughApp.cpp или Module1.vb.
Удалите код, отображаемый в исходном файле, и замените его следующим обновленным кодом. Выберите соответствующий фрагмент кода для конфигурации кода.
using System; using System.Threading; public class ServerClass { static int count = 0; // The method that will be called when the thread is started. public void InstanceMethod() { Console.WriteLine( "ServerClass.InstanceMethod is running on another thread."); int data = count++; // Pause for a moment to provide a delay to make // threads more apparent. Thread.Sleep(3000); Console.WriteLine( "The instance method called by the worker thread has ended. " + data); } } public class Simple { public static void Main() { for (int i = 0; i < 10; i++) { CreateThreads(); } } public static void CreateThreads() { ServerClass serverObject = new ServerClass(); Thread InstanceCaller = new Thread(new ThreadStart(serverObject.InstanceMethod)); // Start the thread. InstanceCaller.Start(); Console.WriteLine("The Main() thread calls this after " + "starting the new InstanceCaller thread."); } }
В меню File (Файл) выберите команду Save All (Сохранить все).
(только Visual Basic) В обозревателе решений (справа) щелкните правой кнопкой мыши узел проекта и выберите "Свойства". На вкладке "Приложение" измените объект Startup на Simple.
Отладка многопоточного приложения
В редакторе исходного кода найдите следующий фрагмент кода:
Щелкните левой кнопкой мыши в левой области
Thread.Sleep
илиstd::this_thread::sleep_for
для C++, чтобы вставить точку останова.В лобовой области красный круг указывает, что точка останова задана в этом расположении.
В меню отладки выберите "Начать отладку " (F5).
Visual Studio создает решение, приложение начинает работать с подключенным отладчиком, а затем приложение останавливается в точке останова.
В редакторе исходного кода найдите строку, содержащую точку останова.
Узнайте о маркере потока
На панели инструментов отладки выберите кнопку «Показать потоки в Source»
.
Дважды нажмите клавишу F11 , чтобы перейти к отладчику.
Посмотрите на водосточный желоб в левой части окна. В этой строке обратите внимание на значок маркера потока
, который напоминает две закрученные нити. Маркер потока указывает, что поток остановлен в этом расположении.
Маркер потока может быть частично скрыт точкой останова.
Наведите указатель мыши на маркер потока. Появится подсказка данных с указанием имени и номера идентификатора потока для каждого остановленного потока. В этом случае имя, вероятно,
<noname>
.Выберите маркер потока, чтобы просмотреть доступные параметры в контекстном меню.
Просмотр расположений потоков
В окне Параллельных стеков можно переключаться между представлением "Потоки" и (для программирования на основе задач) представлением "Задачи", а также просматривать сведения о стеке вызовов для каждого потока. В этом приложении можно использовать представление "Потоки".
Откройте окно параллельных стеков, выбрав "Отладка>параллельных стековWindows>". Вы увидите примерно следующее. Точные сведения могут отличаться в зависимости от текущего расположения каждого потока, оборудования и языка программирования.
В этом примере слева направо мы видим эти сведения для управляемого кода:
- Текущий поток (желтая стрелка) вошел в
ServerClass.InstanceMethod
. Вы можете просмотреть идентификатор потока и кадр стека, наведя указатель мыши наServerClass.InstanceMethod
. - Поток 31724 ожидает получения замка, который принадлежит потоку 20272.
- Основной поток (левая сторона) остановлен на [внешнем коде], который можно просмотреть подробно, если вы выберете "Показать внешний код".
В этом примере слева направо мы видим эти сведения для управляемого кода:
- Основной поток (слева) остановлен на
Thread.Start
, где точка остановки обозначена значком.
- Два потока вошли в
ServerClass.InstanceMethod
, один из которых — текущий поток (желтая стрелка), а другой поток остановился вThread.Sleep
. - Новый поток (справа) также начинается, но останавливается на
ThreadHelper.ThreadStart
.
- Текущий поток (желтая стрелка) вошел в
Чтобы просмотреть потоки в представлении списка, выберите Отладка>Windows>Потоки.
В этом представлении можно легко увидеть, что поток 20272 является основным потоком и в настоящее время находится во внешнем коде, в частности ,System.Console.dll.
Замечание
Дополнительные сведения об использовании окна "Потоки " см. в пошаговом руководстве. Отладка многопоточного приложения.
Щелкните правой кнопкой мыши по записям в окне параллельных стеков или потоков, чтобы просмотреть доступные параметры в контекстном меню.
Вы можете выполнить различные действия из этих меню правой кнопкой мыши. В этом руководстве вы узнаете больше об этих сведениях в окне "Параллельные часы " (следующие разделы).
Установить мониторинг переменной
Откройте окно "Параллельные часы", выбрав "Отладка>параллельных часовWindows>Parallel Watch> 1".
Выберите ячейку, в которой отображается
<Add Watch>
текст (или пустая ячейка заголовка в четвертом столбце) и введитеdata
.Значения переменной данных для каждого потока отображаются в окне.
Выберите ячейку, в которой отображается
<Add Watch>
текст (или пустая ячейка заголовка в пятом столбце) и введитеcount
.Значения переменной
count
для каждого потока отображаются в окне. Если вы еще не видите столько информации, попробуйте несколько раз нажать F11, чтобы продвинуть выполнение потоков в отладчике.Щелкните правой кнопкой мыши одну из строк в окне, чтобы просмотреть доступные параметры.
Отмечать и снимать отметку с тем/записей
Вы можете пометить потоки, чтобы отслеживать важные потоки и игнорировать другие потоки.
В окне параллельных часов удерживайте клавишу SHIFT и выберите несколько строк.
Щелкните правой кнопкой мыши и выберите флаг.
Все выбранные потоки помечены. Теперь можно отфильтровать только помеченные темы.
В окне параллельного просмотра нажмите кнопку "Показать только помеченные потоки " (
).
В списке отображаются только помеченные потоки.
Подсказка
После того как вы пометили некоторые потоки, вы можете щелкнуть правой кнопкой мыши строку кода в редакторе кода и выбрать Запустить помеченные потоки до курсора. Обязательно выберите код, которого достигнут все отмеченные потоки. Visual Studio приостанавливает потоки в выбранной строке кода, что упрощает управление порядком выполнения путем замораживания и оттаивания потоков.
Нажмите кнопку "Показать только помеченные потоки ", чтобы снова переключиться на режим "Показать все потоки ".
Чтобы снять отметку с потоков, щелкните правой кнопкой мыши один или несколько помеченных потоков в окне Параллельного наблюдения и выберите Снять отметку.
Приостановка и возобновление выполнения потока
Подсказка
Вы можете заморозить и разморозить (приостановить и возобновить) потоки, чтобы управлять порядком выполнения работы потоков. Это может помочь вам решить проблемы конкурентного доступа, такие как взаимоблокировки и условия гонки.
В окне Parallel Watch со всеми выбранными строками щелкните правой кнопкой мыши и выберите Закрепить.
Во втором столбце появится значок приостановки для каждой строки. Значок паузы показывает, что поток заморожен.
Отмените выбор всех остальных строк, выбрав только одну строку.
Щелкните правой кнопкой мыши по строке и выберите Разморозить.
Значок приостановки исчезает в этой строке, что указывает, что поток больше не заморожен.
Перейдите в редактор кода и нажмите клавишу F11. Выполняется только размороженный поток.
Приложение также может инициировать некоторые новые потоки. Все новые треды не отмечены и остаются активными.
Следуйте одному потоку с условными точками останова
Это может быть полезно для отслеживания выполнения одного потока в отладчике. Один из способов сделать это - заморозить потоки, которые вам не интересны. В некоторых сценариях может потребоваться проследить за одним потоком без заморозки других потоков, например, для воспроизведения конкретной ошибки. Чтобы следовать потоку без замораживания других потоков, необходимо избежать разрыва в коде, за исключением интересующего вас потока. Эту задачу можно выполнить, задав условную точку останова.
Точки останова можно задать в различных условиях, например имя потока или идентификатор потока. Это может быть полезно, чтобы установить условие для данных, которые, как вы знаете, уникальны для каждого потока. Этот подход часто применяется во время отладки, если вы больше заинтересованы в определенном значении данных, чем в любом конкретном потоке.
Щелкните правой кнопкой мыши точку останова, созданную ранее, и выберите "Условия".
В окне параметров точки останова введите
data == 5
условное выражение.Подсказка
Если вы более заинтересованы в определенном потоке, используйте имя потока или идентификатор потока для условия. Для этого в окне "Параметры точки останова " выберите "Фильтр " вместо условного выражения и следуйте советам по фильтрации. Возможно, вам потребуется присвоить имена потоков в коде приложения, так как идентификаторы потоков изменяются при перезапуске отладчика.
Закройте окно параметров точки останова .
Нажмите кнопку
, чтобы перезапустить сеанс отладки.
Вы переходите к коду в потоке, где значение переменной данных равно 5. В окне параллельного просмотра найдите желтую стрелку, указывающую текущий контекст отладчика.
Теперь можно перейти через код (F10) и перейти в код (F11) и следить за выполнением одного потока.
До тех пор, пока условие точки останова уникально для потока, и отладчик не попадает в другие точки останова на других потоках (может потребоваться отключить их), вы можете перейти к коду и перейти к коду без переключения на другие потоки.
Замечание
При продолжении работы отладчика все потоки будут выполняться. Однако отладчик не будет останавливать выполнение кода в других потоках, пока один из них не попадет в точку останова.