Začínáme s laděním vícevláknových aplikací (C#, Visual Basic, C++)

Visual Studio poskytuje několik nástrojů a prvků uživatelského rozhraní, které vám pomůžou ladit vícevláknové aplikace. V tomto kurzu se dozvíte, jak používat značky vláken, okno Paralelní zásobníky , okno Paralelní sledování , podmíněné zarážky a zarážky filtru. Dokončení tohoto kurzu vás seznámí s funkcemi sady Visual Studio pro ladění vícevláknových aplikací.

Tyto dva články obsahují další informace o používání dalších nástrojů pro ladění s více vlákny:

  • Pokud chcete použít panel nástrojů Umístění ladění a okno Vlákna , přečtěte si téma Návod: Ladění vícevláknové aplikace.

  • Ukázku, která používá Task (spravovaný kód) a modul concurrency runtime (C++), najdete v tématu Návod: Ladění paralelní aplikace. Obecné tipy pro ladění, které platí pro většinu typů vícevláknových aplikací, najdete v tomto článku i v tomto článku.

Prvním krokem je vytvoření projektu vícevláknové aplikace.

Vytvoření projektu vícevláknové aplikace

  1. Otevřete Visual Studio a vytvořte nový projekt.

    Pokud úvodní okno není otevřené, zvolte Okno Start souboru>.

    V úvodním okně zvolte Vytvořit nový projekt.

    V okně Vytvořit nový projekt zadejte nebo zadejte konzolu do vyhledávacího pole. Dále v seznamu jazyků zvolte C#, C++ nebo Visual Basic a pak v seznamu Platformy zvolte Windows .

    Po použití filtrů jazyka a platformy zvolte šablonu konzolové aplikace pro .NET nebo C++ a pak zvolte Další.

    Poznámka:

    Pokud nevidíte správnou šablonu, přejděte do části Nástroje Získat nástroje>a funkce..., čímž se otevře Instalační program pro Visual Studio. Zvolte vývoj desktopových aplikací .NET nebo vývoj desktopových aplikací pomocí úlohy C++ a pak zvolte Upravit.

    V okně Konfigurovat nový projekt zadejte nebo zadejte MyThreadWalkthroughApp do pole Název projektu. Pak zvolte Možnost Další nebo Vytvořit podle toho, která možnost je k dispozici.

    Pro projekt .NET Core nebo .NET 5+ zvolte buď doporučenou cílovou architekturu, nebo .NET 8, a pak zvolte Vytvořit.

    Zobrazí se nový projekt konzoly. Po vytvoření projektu se zobrazí zdrojový soubor. V závislosti na zvoleném jazyce se zdrojový soubor může volat Program.cs, MyThreadWalkthroughApp.cpp nebo Module1.vb.

  2. Odstraňte kód, který se zobrazí ve zdrojovém souboru, a nahraďte ho následujícím aktualizovaným kódem. Zvolte odpovídající fragment kódu pro konfiguraci kódu.

    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.");
    
        }
    }
    
  3. V nabídce File (Soubor) vyberte Save All (Uložit vše).

  4. (Jenom Visual Basic) V Průzkumník řešení (pravé podokno) klikněte pravým tlačítkem myši na uzel projektu a zvolte Vlastnosti. Na kartě Aplikace změňte objekt Po spuštění na Jednoduchý.

Ladění vícevláknové aplikace

  1. V editoru zdrojového kódu vyhledejte následující fragment kódu:

    Thread.Sleep(3000);
    Console.WriteLine();
    
  2. Kliknutím levým tlačítkem myši do levého hřbetu Thread.Sleep příkazu nebo pro jazyk C++ std::this_thread::sleep_for vložte novou zarážku.

    V hřbetu červený kruh označuje, že zarážka je nastavena na tomto místě.

  3. V nabídce Ladění vyberte Spustit ladění (F5).

    Visual Studio toto řešení sestaví, aplikace se spustí s připojeným ladicím programem a pak se aplikace zastaví na zarážce.

  4. V editoru zdrojového kódu vyhledejte řádek obsahující zarážku.

Zjištění značky vlákna

  1. Na panelu nástrojů Ladění vyberte tlačítko Zobrazit vlákna ve zdroji Zobrazit vlákna ve zdroji.

  2. Stisknutím klávesy F11 přechádněte ladicí program.

  3. Podívejte se na hřbet na levé straně okna. Na tomto řádku si všimněte ikony Značka vlákna značky vlákna, která se podobá dvěma krouceným vláknům. Značka vlákna označuje, že vlákno je v tomto umístění zastaveno.

    Značka vlákna může být částečně skryta zarážkou.

  4. Najeďte myší na značku vlákna. Zobrazí se popis dat s názvem a číslem ID vlákna pro každé zastavené vlákno. V tomto případě je název pravděpodobně <noname>.

    Snímek obrazovky s ID vlákna v datovém tipu

  5. Výběrem značky vlákna zobrazíte dostupné možnosti v místní nabídce.

Zobrazení umístění vláken

V okně Paralelní zásobníky můžete přepínat mezi zobrazením vláken a zobrazením úloh založeným na úlohách a zobrazit informace zásobníku volání pro každé vlákno. V této aplikaci můžeme použít zobrazení Vlákna.

  1. Otevřete okno Paralelní zásobníky tak, že zvolíte Ladění>paralelních zásobníků Windows.> Mělo by se zobrazit něco podobného jako v následujícím příkladu. Přesné informace se můžou lišit v závislosti na aktuálním umístění jednotlivých vláken, hardwaru a programovacího jazyka.

    Snímek obrazovky s oknem Paralelní zásobníky

    V tomto příkladu zleva doprava vidíme tyto informace pro spravovaný kód:

    • Aktuální vlákno (žlutá šipka) bylo zadáno ServerClass.InstanceMethod. ID vlákna a rámec zásobníku vlákna můžete zobrazit tak, že na něj najedete ServerClass.InstanceMethodmyší.
    • Vlákno 31724 čeká na zámek vlastněný vláknem 20272.
    • Hlavní vlákno (vlevo) se zastavilo na [Externí kód], které můžete zobrazit podrobně, pokud zvolíte Zobrazit externí kód.

    Okno Paralelní zásobníky

    V tomto příkladu zleva doprava vidíme tyto informace pro spravovaný kód:

    • Hlavní vlákno (levá strana) se zastavilo , Thread.Startkde je bod zastavení identifikován ikonou Značka vláknaznačky vlákna .
    • Dvě vlákna vstoupily do ServerClass.InstanceMethod, z nichž jeden je aktuální vlákno (žlutá šipka), zatímco druhé vlákno se zastavilo .Thread.Sleep
    • Začíná se také nové vlákno (vpravo), ale je zastaveno ThreadHelper.ThreadStart.
  2. Chcete-li zobrazit vlákna v zobrazení seznamu, vyberte Ladit>vlákna systému Windows.>

    Snímek obrazovky s oknem Vlákna

    V tomto zobrazení můžete snadno vidět, že vlákno 20272 je hlavní vlákno a aktuálně se nachází v externím kódu, konkrétně System.Console.dll.

    Poznámka:

    Další informace o použití okna Vlákna naleznete v tématu Návod: Ladění vícevláknové aplikace.

  3. Po kliknutí pravým tlačítkem myši v okně Paralelní zásobníky nebo vlákna zobrazíte dostupné možnosti v místní nabídce.

    Z těchto nabídek po kliknutí pravým tlačítkem myši můžete provádět různé akce. V tomto kurzu prozkoumáte další podrobnosti v okně paralelního sledování (další části).

Nastavení kukátku na proměnné

  1. Otevřete okno Paralelní kukátko výběrem možnosti Ladit>paralelní hodinky Windows>Parallel Watch>1.

  2. Vyberte buňku <Add Watch> , ve které vidíte text (nebo prázdnou buňku záhlaví ve čtvrtém sloupci) a zadejte data.

    Hodnoty datové proměnné pro každé vlákno se zobrazí v okně.

  3. Vyberte buňku <Add Watch> , ve které vidíte text (nebo prázdnou buňku záhlaví v pátém sloupci) a zadejte count.

    Hodnoty proměnné pro count každé vlákno se zobrazí v okně. Pokud ještě tyto informace nevidíte, zkuste několikrát stisknout klávesu F11 , abyste mohli přejít na provádění vláken v ladicím programu.

    Okno paralelního kukátka

  4. Kliknutím pravým tlačítkem myši na jeden z řádků v okně zobrazíte dostupné možnosti.

Označení a odstranění označení vlákna

Vlákna můžete označit příznakem, abyste mohli sledovat důležitá vlákna a ignorovat ostatní vlákna.

  1. V okně Paralelní kukátko podržte klávesu Shift a vyberte více řádků.

  2. Klikněte pravým tlačítkem myši a vyberte Příznak.

    Všechna vybraná vlákna jsou označena příznakem. Teď můžete filtrovat tak, aby zobrazovala pouze vlákna označená příznakem.

  3. V okně Paralelní kukátko vyberte tlačítko Zobrazit vlákna s příznakemZobrazit pouze vlákna s příznakem .

    V seznamu se zobrazí pouze vlákna s příznakem.

    Tip

    Po označení některých vláken můžete kliknout pravým tlačítkem myši na řádek kódu v editoru kódu a zvolit Spustit vlákna s příznakem kurzoru. Nezapomeňte zvolit kód, ke kterému budou mít přístup všechna vlákna označená příznakem. Visual Studio pozastaví vlákna na vybraném řádku kódu, což usnadňuje řízení pořadí provádění ukotvením a rozmrznutím vláken.

  4. Znovu vyberte tlačítko Zobrazit pouze vlákna s příznakem a přepněte zpět do režimu Zobrazit všechna vlákna.

  5. Pokud chcete zrušit označení vláken, klikněte pravým tlačítkem myši na jedno nebo více vláken s příznakem v okně Paralelní kukátko a vyberte Zrušit označení.

Ukotvení a rozmrznutí provádění vlákna

Tip

Můžete ukotvit a rozmrazit vlákna (pozastavit a obnovit) a řídit pořadí, ve kterém vlákna provádějí práci. To vám může pomoct při řešení problémů se souběžností, jako jsou zablokování a podmínky časování.

  1. V okně Paralelní sledování se všemi vybranými řádky klikněte pravým tlačítkem myši a vyberte Ukotvit.

    Ve druhém sloupci se pro každý řádek zobrazí ikona pozastavení. Ikona pozastavení označuje, že vlákno je ukotvené.

  2. Zrušte výběr všech ostatních řádků tak, že vyberete jenom jeden řádek.

  3. Klikněte pravým tlačítkem myši na řádek a vyberte Thaw.

    Ikona pozastavení zmizí na tomto řádku, což znamená, že vlákno už není ukotvené.

  4. Přepněte do editoru kódu a stiskněte klávesu F11. Spustí se pouze vlákno unfrozen.

    Aplikace může také vytvořit instanci některých nových vláken. Všechna nová vlákna nejsou zmrzlá a nezablokují se.

Sledování jednoho vlákna s podmíněnými zarážky

Může být užitečné sledovat provádění jednoho vlákna v ladicím programu. Jedním ze způsobů, jak to udělat, je zmrazení vláken, které vás nezajímají. V některých scénářích možná budete muset postupovat podle jednoho vlákna, aniž byste zamrzli jiná vlákna, například k reprodukci konkrétní chyby. Pokud chcete sledovat vlákno bez ukotvení jiných vláken, musíte se vyhnout rozdělení kódu s výjimkou vlákna, které vás zajímá. Tuto úlohu můžete provést nastavením podmíněné zarážky.

Zarážky můžete nastavit pro různé podmínky, například název vlákna nebo ID vlákna. Může být užitečné nastavit podmínku pro data, která znáte, je pro každé vlákno jedinečné. Tento přístup je při ladění běžný, pokud vás zajímá více konkrétních hodnot dat než v jakémkoli konkrétním vlákně.

  1. Klikněte pravým tlačítkem myši na zarážku, kterou jste vytvořili dříve, a vyberte Podmínky.

  2. V okně Nastavení zarážky zadejte data == 5 podmíněný výraz.

    Podmíněná zarážka

    Tip

    Pokud vás více zajímá konkrétní vlákno, použijte pro podmínku název vlákna nebo ID vlákna. Pokud to chcete udělat v okně Zarážky Nastavení, vyberte místo podmíněného výrazu filtr filtr a postupujte podle tipů pro filtrování. Při restartování ladicího programu můžete chtít pojmenovat vlákna v kódu aplikace, protože se při restartování ladicího programu změní ID vláken.

  3. Zavřete okno Nastavení zarážky.

  4. Vyberte tlačítko Restartovat Restartování aplikace a restartujte ladicí relaci.

    Na vlákně, kde je hodnota datové proměnné 5, rozdělíte kód. V okně Paralelní kukátko vyhledejte žlutou šipku označující kontext aktuálního ladicího programu.

  5. Teď můžete přejít přes kód (F10) a přejít do kódu (F11) a postupovat podle provádění jednoho vlákna.

    Pokud je podmínka zarážky jedinečná pro vlákno a ladicí program nenarazí na žádné další zarážky v jiných vláknech (možná je budete muset zakázat), můžete přejít přes kód a krokovat do kódu, aniž byste přešli na jiná vlákna.

    Poznámka:

    Když přejdete do ladicího programu, spustí se všechna vlákna. Ladicí program se ale nebude rozdělovat na kód v jiných vláknech, pokud některé z dalších vláken nenarazí na zarážku.