Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Visual Studio biedt verschillende hulpprogramma's en elementen van de gebruikersinterface waarmee u fouten kunt opsporen in toepassingen met meerdere threads. In deze handleiding ziet u hoe u thread-markeringen, het venster Parallelle stacks, het venster Parallel Watch, voorwaardelijke onderbrekingspunten en filteronderbrekingspunten gebruikt. Als u deze zelfstudie voltooit, wordt u vertrouwd met Visual Studio-functies voor het opsporen van fouten in multithreaded-toepassingen.
Zie de volgende artikelen voor zelfstudies die meer gericht zijn op scenario's.
De eerste stap is het maken van een multithreaded toepassingsproject.
Een multithreaded app-project maken
Open Visual Studio en maak een nieuw project.
Als het startvenster niet is geopend, kiest u Bestand>Startvenster.
Kies in het startvenster Een nieuw project maken.
In het venster Een nieuw project maken voer console in het zoekvak in. Kies vervolgens C#, C++of Visual Basic in de lijst Taal en kies Vervolgens Windows in de lijst Platform.
Nadat u de taal- en platformfilters hebt toegepast, kiest u de console-app-sjabloon voor .NET of C++ en kiest u vervolgens Volgende.
Opmerking
Als u de juiste sjabloon niet ziet, gaat u naar Tools>Get Tools and Features..., waarmee het installatieprogramma van Visual Studio wordt geopend. Kies de .NET-desktopontwikkeling of desktopontwikkeling met C++ -werkbelasting en kies Vervolgens Wijzigen.
Typ of voer in het venster Uw nieuwe project configurerenMyThreadWalkthroughApp in het vak Projectnaam in. Kies vervolgens Volgende of Maken, afhankelijk van welke optie beschikbaar is.
Kies voor een .NET Core- of .NET 5+-project het aanbevolen doelframework of .NET 8 en kies vervolgens Maken.
Er verschijnt een nieuw consoleproject. Nadat het project is gemaakt, wordt er een bronbestand weergegeven. Afhankelijk van de taal die u hebt gekozen, wordt het bronbestand mogelijk Program.cs, MyThreadWalkthroughApp.cpp of Module1.vb genoemd.
Verwijder de code die wordt weergegeven in het bronbestand en vervang deze door de volgende bijgewerkte code. Kies het juiste codefragment voor de codeconfiguratie.
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."); } }Selecteer in het menu Bestand de optie Alles opslaan.
(Alleen Visual Basic) Klik in Solution Explorer (rechterdeelvenster) met de rechtermuisknop op het projectknooppunt en kies Eigenschappen. Wijzig op het tabblad Toepassing het opstartobject in Simple.
Fouten opsporen in de multithreaded-app
Zoek in de broncode-editor naar het volgende codefragment:
Klik met de linkermuisknop in de linkergoot van de
Thread.Sleepof, voor C++,std::this_thread::sleep_forom een nieuw onderbrekingspunt in te voegen.In de kantlijn geeft een rode cirkel aan dat op deze locatie een onderbrekingspunt is ingesteld.
Selecteer in het menu Foutopsporing de foutopsporing starten (F5).
Visual Studio bouwt de oplossing, de app wordt uitgevoerd met het foutopsporingsprogramma gekoppeld en vervolgens stopt de app bij het onderbrekingspunt.
Zoek in de broncode-editor de regel die het onderbrekingspunt bevat.
Ontdek de draadmarkering
Selecteer in de werkbalk Foutopsporing de knop Threads weergeven in de knop
.Druk tweemaal op F11 om het foutopsporingsprogramma verder te gaan.
Kijk naar de goot aan de linkerkant van het raam. Op deze regel ziet u een draadmarkeerpictogram
dat lijkt op twee gedraaide draden. De threadmarkering geeft aan dat een thread op deze locatie is gestopt.Een threadmarkering kan gedeeltelijk worden verborgen door een breekpunt.
Beweeg de aanwijzer over de draadmarker. Er wordt een DataTip weergegeven met de naam en het thread-id-nummer voor elke gestopte thread. In dit geval is de naam waarschijnlijk
<noname>.
Selecteer de draadmarkering om de beschikbare opties in het snelmenu weer te geven.
De threadlocaties weergeven
In het venster Parallelle stacks kunt u schakelen tussen een Threads-weergave en (voor taakgebaseerde programmering) takenweergave en kunt u gespreksstackgegevens voor elke thread weergeven. In deze app kunnen we de weergave Threads gebruiken.
Open het venster Parallelle stacks door Fouten opsporen> inWindows>Parallel Stacks te kiezen. U zou iets vergelijkbaars als het volgende moeten zien. De exacte informatie kan verschillen, afhankelijk van de huidige locatie van elke thread, uw hardware en uw programmeertaal.
In dit voorbeeld zien we van links naar rechts deze informatie voor beheerde code:
- De huidige thread (gele pijl) is binnengekomen
ServerClass.InstanceMethod. U kunt de thread-id en het stackframe van een thread bekijken door de muisaanwijzer overServerClass.InstanceMethodte bewegen. - Thread 31724 wacht op een vergrendeling die eigendom is van Thread 20272.
- De hoofdthread (links) is gestopt op [Externe code], die u in detail kunt bekijken als u Externe code weergeven kiest.
In dit voorbeeld zien we van links naar rechts deze informatie voor beheerde code:
- De hoofd-thread aan de linkerkant is gestopt op
Thread.Start, waarbij het stoppunt wordt geïdentificeerd door het threadmarkeringspictogram
. - Er zijn twee threads binnengekomen in
ServerClass.InstanceMethod, waarvan de ene de huidige thread (gele pijl) is, terwijl de andere thread is gestopt inThread.Sleep. - Een nieuwe thread (aan de rechterkant) wordt ook gestart, maar stopt bij
ThreadHelper.ThreadStart.
- De huidige thread (gele pijl) is binnengekomen
Selecteer Debug>Windows>Threads om de threads in een lijstweergave te bekijken.
In deze weergave kunt u gemakkelijk zien dat thread 20272 de hoofdthread is en zich momenteel in externe code bevindt, met name System.Console.dll.
Klik met de rechtermuisknop op items in het venster Parallelle stapels of Threads om de beschikbare opties in het snelmenu weer te geven.
U kunt verschillende acties uitvoeren vanuit deze snelmenu's. Voor deze zelfstudie verkent u meer van deze details in het venster Parallel Watch (volgende secties).
Een horloge instellen op een variabele
Open het venster Parallel Watch door Fouten opsporen> inWindows>Parallel Watch>Parallel Watch 1 te selecteren.
Selecteer de cel waarin u de
<Add Watch>tekst ziet (of de lege koptekstcel in de vierde kolom) en voer deze indata.De waarden voor de gegevensvariabele voor elke thread worden weergegeven in het venster.
Selecteer de cel waarin u de
<Add Watch>tekst ziet (of de lege koptekstcel in de vijfde kolom) en voer deze incount.De waarden voor de
countvariabele voor elke thread worden weergegeven in het venster. Als u deze informatie nog niet ziet, drukt u een paar keer op F11 om de uitvoering van de threads in de debugger te bevorderen.
Klik met de rechtermuisknop op een van de rijen in het venster om de beschikbare opties weer te geven.
Threads markeren en markeringen verwijderen
U kunt threads markeren om belangrijke threads bij te houden en de andere threads te negeren.
Houd de Shift-toets ingedrukt in het venster Parallel Watch en selecteer meerdere rijen.
Klik met de rechtermuisknop en selecteer Vlag.
Alle geselecteerde threads worden gemarkeerd. U kunt nu filteren om alleen gemarkeerde threads weer te geven.
Selecteer in het venster Parallel Watch de knop Alleen gemarkeerde threads weergeven met
.Alleen de gemarkeerde threads worden weergegeven in de lijst.
Aanbeveling
Nadat u een aantal threads hebt gemarkeerd, kunt u met de rechtermuisknop op een coderegel in de code-editor klikken en gemarkeerde threads uitvoeren op Cursor kiezen. Zorg ervoor dat u code kiest die alle gemarkeerde threads bereiken. Visual Studio onderbreekt threads op de geselecteerde coderegel, waardoor het eenvoudiger is om de volgorde van uitvoering te beheren door threads te blokkeren en te ontdooien.
Selecteer opnieuw de knop Alleen gemarkeerde threads weergeven om terug te schakelen naar de modus Alle threads weergeven .
Als u threads wilt verwijderen, klikt u met de rechtermuisknop op een of meer gemarkeerde threads in het venster Parallel Watch en selecteert u Unflag.
Threaduitvoering blokkeren en ontdooien
Aanbeveling
U kunt threads blokkeren en ontdooien (onderbreken en hervatten) om de volgorde te bepalen waarin threads werken. Dit kan u helpen bij het oplossen van gelijktijdigheidsproblemen, zoals deadlocks en racecondities.
Klik in het venster Parallel Watch met alle geselecteerde rijen met de rechtermuisknop en selecteer Blokkeren.
In de tweede kolom wordt voor elke rij een pauzepictogram weergegeven. Het onderbrekingspictogram geeft aan dat de thread is geblokkeerd.
Hef alle andere rijen op door slechts één rij te selecteren.
Klik met de rechtermuisknop op een rij en selecteer Ontdooien.
Het onderbrekingspictogram gaat weg op deze rij, wat aangeeft dat de thread niet meer is geblokkeerd.
Schakel over naar de code-editor en druk op F11. Alleen de niet-bevroren thread wordt uitgevoerd.
De app kan ook enkele nieuwe threads instantiëren. Nieuwe threads worden niet gemarkeerd en worden niet bevroren.
Eén thread volgen met voorwaardelijke onderbrekingspunten
Het kan handig zijn om de uitvoering van één thread in het foutopsporingsprogramma te volgen. Een manier om dat te doen, is door threads te blokkeren waarin u niet geïnteresseerd bent. In sommige scenario's moet u mogelijk één thread volgen zonder andere threads te blokkeren, bijvoorbeeld om een bepaalde fout te reproduceren. Als u een thread wilt volgen zonder andere threads te blokkeren, moet u voorkomen dat u code inbreekt, behalve de thread waarin u geïnteresseerd bent. U kunt deze taak uitvoeren door een voorwaardelijk onderbrekingspunt in te stellen.
U kunt onderbrekingspunten instellen op verschillende voorwaarden, zoals de naam van de thread of de thread-id. Het kan handig zijn om de voorwaarde in te stellen voor gegevens die u kent die uniek zijn voor elke thread. Deze benadering is gebruikelijk tijdens foutopsporing wanneer u meer geïnteresseerd bent in een bepaalde gegevenswaarde dan in een bepaalde thread.
Klik met de rechtermuisknop op het onderbrekingspunt dat u eerder hebt gemaakt en selecteer Voorwaarden.
Voer in het venster
data == 5de voorwaardelijke expressie in.
Aanbeveling
Als u meer geïnteresseerd bent in een specifieke thread, gebruikt u een threadnaam of thread-id als voorwaarde. Als u dit wilt doen in het venster Instellingen voor onderbrekingspunten , selecteert u Filteren in plaats van voorwaardelijke expressie en volgt u de filtertips. Mogelijk wilt u uw threads een naam geven in uw app-code, omdat thread-id's veranderen wanneer u het foutopsporingsprogramma opnieuw start.
Sluit het venster Instellingen voor onderbrekingspunten .
Selecteer de knop
om uw foutopsporingssessie opnieuw op te starten.U breekt code in op de thread waarin de waarde van de gegevensvariabele 5 is. Zoek in het venster Parallel Watch naar de gele pijl die de huidige foutopsporingsprogrammacontext aangeeft.
Nu kunt u stap over code (F10) en stap in code (F11) en de uitvoering van de individuele thread volgen.
Zolang de onderbrekingspuntvoorwaarde uniek is voor de thread en het foutopsporingsprogramma geen andere onderbrekingspunten op andere threads bereikt (u moet deze mogelijk uitschakelen), kunt u de code doorlopen en in code stappen zonder over te schakelen naar andere threads.
Opmerking
Wanneer u doorgaat met de debugger, worden alle threads uitgevoerd. Het foutopsporingsprogramma zal echter niet inbreken in de code van andere threads, tenzij een van de andere threads een breekpunt raakt.