Sdílet prostřednictvím


Návod: Ladění paralelní aplikace v sadě Visual Studio (C#, Visual Basic, C++)

Tento návod ukazuje, jak pomocí oken Paralelní úlohy a Paralelní zásobníky ladit paralelní aplikaci. Tato okna vám pomůžou pochopit a ověřit chování kódu za běhu, který používá knihovnu TPL (Task Parallel Library) nebo Concurrency Runtime. Tento názorný postup obsahuje ukázkový kód, který obsahuje předdefinované zarážky. Po přerušení kódu názorný postup ukazuje, jak pomocí oken Paralelní úlohy a Paralelní zásobníky jej prozkoumat.

V tomto názorném postupu se naučíte tyto úlohy:

  • Jak zobrazit zásobníky volání všech vláken v jednom zobrazení.

  • Jak zobrazit seznam instancí System.Threading.Tasks.Task, které byly vytvořeny ve vaší aplikaci.

  • Jak zobrazit skutečné zásobníky volání úloh místo těch ve vláknech.

  • Jak přejít na kód z oken Paralelní úlohy a Paralelní zásobníky

  • Jak se okna vyrovnávají se škálováním prostřednictvím seskupení, přiblížení a dalších souvisejících funkcí.

Požadavky

V tomto názorném postupu se předpokládá, že je Just My Code povolený (ve výchozím nastavení je povolený v novějších verzích Visual Studio). V nabídce Nástroje vyberte Možnosti, rozbalte uzel Ladění, vyberte Obecné a pak vyberte Povolit pouze můj kód (pouze spravované). Pokud tuto funkci nenastavíte, můžete tento názorný postup použít, ale výsledky se můžou lišit od ilustrací.

Ukázka v jazyce C#

Pokud použijete ukázku jazyka C#, předpokládá se také, že externí kód je skrytý. Pokud chcete přepnout, jestli se zobrazí externí kód, klikněte pravým tlačítkem myši na záhlaví tabulky Název okna Zásobník volání a pak vyberte nebo zrušte zaškrtnutí políčka Zobrazit externí kód. Pokud tuto funkci nenastavíte, můžete tento názorný postup použít, ale výsledky se můžou lišit od ilustrací.

Ukázka jazyka C++

Pokud použijete ukázku jazyka C++, můžete ignorovat odkazy na externí kód v tomto článku. Externí kód se vztahuje pouze na ukázku jazyka C#.

Ilustrace

Ilustrace v tomto článku jsou zaznamenány na čtyřjádrový počítač se spuštěnou ukázkou jazyka C#. I když k dokončení tohoto návodu můžete použít jiné konfigurace, můžou se ilustrace lišit od toho, co se zobrazuje na vašem počítači.

Vytvoření ukázkového projektu

Vzorový kód v tomto názorném postupu je určen pro aplikaci, která nic nedělá. Účelem tohoto cvičení je pochopit, jak pomocí oken nástrojů ladit paralelní aplikaci.

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

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

    V úvodním okně zvolte Nový projekt.

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

    V okně Vytvořit nový projekt 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 konzolovou aplikaci pro .NET Core nebo C++ a pak zvolte Další.

    Poznámka:

    Pokud nevidíte správnou šablonu, přejděte na NástrojeZískat nástroje >a funkce..., čímž se otevře instalační program sady 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 název nebo do pole Název projektu použijte výchozí název. Potom zvolte Další nebo Vytvořit podle toho, která možnost je k dispozici.

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

    Zobrazí se nový konzolový projekt. Po vytvoření projektu se zobrazí zdrojový soubor.

  2. Otevřete soubor kódu .cpp, .cs nebo .vb v projektu. Odstraňte jeho obsah a vytvořte prázdný soubor kódu.

  3. Do prázdného souboru kódu vložte následující kód pro vybraný jazyk.

    using System;
    using System.Threading;
    using System.Threading.Tasks;
    using System.Diagnostics;
    
    class S
    {
      static void Main()
      {
        pcount = Environment.ProcessorCount;
        Console.WriteLine("Proc count = " + pcount);
        ThreadPool.SetMinThreads(4, -1);
        ThreadPool.SetMaxThreads(4, -1);
    
        t1 = new Task(A, 1);
        t2 = new Task(A, 2);
        t3 = new Task(A, 3);
        t4 = new Task(A, 4);
        Console.WriteLine("Starting t1 " + t1.Id.ToString());
        t1.Start();
        Console.WriteLine("Starting t2 " + t2.Id.ToString());
        t2.Start();
        Console.WriteLine("Starting t3 " + t3.Id.ToString());
        t3.Start();
        Console.WriteLine("Starting t4 " + t4.Id.ToString());
        t4.Start();
    
        Console.ReadLine();
      }
    
      static void A(object o)
      {
        B(o);
      }
      static void B(object o)
      {
        C(o);
      }
      static void C(object o)
      {
        int temp = (int)o;
    
        Interlocked.Increment(ref aa);
        while (aa < 4)
        {
          ;
        }
    
        if (temp == 1)
        {
          // BP1 - all tasks in C
          Debugger.Break();
          waitFor1 = false;
        }
        else
        {
          while (waitFor1)
          {
            ;
          }
        }
        switch (temp)
        {
          case 1:
            D(o);
            break;
          case 2:
            F(o);
            break;
          case 3:
          case 4:
            I(o);
            break;
          default:
            Debug.Assert(false, "fool");
            break;
        }
      }
      static void D(object o)
      {
        E(o);
      }
      static void E(object o)
      {
        // break here at the same time as H and K
        while (bb < 2)
        {
          ;
        }
        //BP2 - 1 in E, 2 in H, 3 in J, 4 in K
        Debugger.Break();
        Interlocked.Increment(ref bb);
    
        //after
        L(o);
      }
      static void F(object o)
      {
        G(o);
      }
      static void G(object o)
      {
        H(o);
      }
      static void H(object o)
      {
        // break here at the same time as E and K
        Interlocked.Increment(ref bb);
        Monitor.Enter(mylock);
        while (bb < 3)
        {
          ;
        }
        Monitor.Exit(mylock);
    
    
        //after
        L(o);
      }
      static void I(object o)
      {
        J(o);
      }
      static void J(object o)
      {
        int temp2 = (int)o;
    
        switch (temp2)
        {
          case 3:
            t4.Wait();
            break;
          case 4:
            K(o);
            break;
          default:
            Debug.Assert(false, "fool2");
            break;
        }
      }
      static void K(object o)
      {
        // break here at the same time as E and H
        Interlocked.Increment(ref bb);
        Monitor.Enter(mylock);
        while (bb < 3)
        {
          ;
        }
        Monitor.Exit(mylock);
    
    
        //after
        L(o);
      }
      static void L(object oo)
      {
        int temp3 = (int)oo;
    
        switch (temp3)
        {
          case 1:
            M(oo);
            break;
          case 2:
            N(oo);
            break;
          case 4:
            O(oo);
            break;
          default:
            Debug.Assert(false, "fool3");
            break;
        }
      }
      static void M(object o)
      {
        // breaks here at the same time as N and Q
        Interlocked.Increment(ref cc);
        while (cc < 3)
        {
          ;
        }
        //BP3 - 1 in M, 2 in N, 3 still in J, 4 in O, 5 in Q
        Debugger.Break();
        Interlocked.Increment(ref cc);
        while (true)
          Thread.Sleep(500); // for ever
      }
      static void N(object o)
      {
        // breaks here at the same time as M and Q
        Interlocked.Increment(ref cc);
        while (cc < 4)
        {
          ;
        }
        R(o);
      }
      static void O(object o)
      {
        Task t5 = Task.Factory.StartNew(P, TaskCreationOptions.AttachedToParent);
        t5.Wait();
        R(o);
      }
      static void P()
      {
        Console.WriteLine("t5 runs " + Task.CurrentId.ToString());
        Q();
      }
      static void Q()
      {
        // breaks here at the same time as N and M
        Interlocked.Increment(ref cc);
        while (cc < 4)
        {
          ;
        }
        // task 5 dies here freeing task 4 (its parent)
        Console.WriteLine("t5 dies " + Task.CurrentId.ToString());
        waitFor5 = false;
      }
      static void R(object o)
      {
        if ((int)o == 2)
        {
          //wait for task5 to die
          while (waitFor5) { ;}
    
    
          int i;
          //spin up all procs
          for (i = 0; i < pcount - 4; i++)
          {
            Task t = Task.Factory.StartNew(() => { while (true);});
            Console.WriteLine("Started task " + t.Id.ToString());
          }
    
          Task.Factory.StartNew(T, i + 1 + 5, TaskCreationOptions.AttachedToParent); //scheduled
          Task.Factory.StartNew(T, i + 2 + 5, TaskCreationOptions.AttachedToParent); //scheduled
          Task.Factory.StartNew(T, i + 3 + 5, TaskCreationOptions.AttachedToParent); //scheduled
          Task.Factory.StartNew(T, i + 4 + 5, TaskCreationOptions.AttachedToParent); //scheduled
          Task.Factory.StartNew(T, (i + 5 + 5).ToString(), TaskCreationOptions.AttachedToParent); //scheduled
    
          //BP4 - 1 in M, 2 in R, 3 in J, 4 in R, 5 died
          Debugger.Break();
        }
        else
        {
          Debug.Assert((int)o == 4);
          t3.Wait();
        }
      }
      static void T(object o)
      {
        Console.WriteLine("Scheduled run " + Task.CurrentId.ToString());
      }
      static Task t1, t2, t3, t4;
      static int aa = 0;
      static int bb = 0;
      static int cc = 0;
      static bool waitFor1 = true;
      static bool waitFor5 = true;
      static int pcount;
      static S mylock = new S();
    }
    

Po aktualizaci souboru kódu uložte změny a sestavte řešení.

  1. V nabídce Soubor vyberte Uložit vše.

  2. V nabídce Sestavení vyberte Znovu sestavit řešení.

Všimněte si, že existují čtyři volání Debugger.Break (DebugBreak v ukázce jazyka C++). Proto nemusíte vkládat body přerušení. Při spuštění aplikace se program v ladicím režimu může až čtyřikrát zastavit.

Použijte okno Paralelní zásobníky: Zobrazení vláken

Začněte tak, že v nabídce Laděnívyberete Spustit ladění. Počkejte, až se dosáhne prvního bodu přerušení.

Zobrazit zásobník volání pro jedno vlákno

  1. V nabídce Ladění přejděte na Windows a pak vyberte Vlákna. Ukotvěte okno Vlákna do spodní části sady Visual Studio.

  2. V nabídce Ladění přejděte na Windows a pak vyberte Zásobník volání. Ukotvěte okno Zásobník volání ve spodní části aplikace Visual Studio.

  3. Poklikejte na vlákno v okně Vlákna , aby bylo aktuální. Aktuální vlákna mají žlutou šipku. Když změníte aktuální vlákno, jeho zásobník volání se zobrazí v okně Zásobník volání .

Prozkoumejte okno Paralelních zásobníků

V nabídce Ladění přejděte na Windows a pak vyberte Paralelní zásobníky. Ujistěte se, že je v poli v levém horním rohu vybrán Threads.

Pomocí okna Paralelní zásobníky můžete zobrazit více zásobníků volání najednou v jednom zobrazení. Následující obrázek znázorňuje okno Paralelní zásobníky, které se nachází nad oknem Zásobník volání.

Snímek obrazovky pohledu vláken v okně paralelní zásobníky

Zobrazení vláken v okně Paralelní zásobníky

Zásobník volání hlavního vlákna se zobrazí v jednom poli a zásobníky volání pro ostatní čtyři vlákna jsou seskupeny do jiného pole. Čtyři vlákna jsou seskupena dohromady, protože jejich zásobníkové rámce sdílejí stejné kontexty metody; to znamená, že jsou ve stejných metodách: A, B a C. Pokud chcete zobrazit ID vláken a názvy vláken, které sdílejí stejné pole, najeďte myší na pole se záhlavím ([#] Vlákna). Aktuální vlákno se zobrazí tučně.

Snímek obrazovky ukazující popisek, který zobrazuje ID a názvy vláken.

Popis, který zobrazuje ID a názvy vláken

Žlutá šipka označuje aktivní rámec zásobníku aktuálního vlákna.

Úroveň podrobností pro snímky zásobníku (Názvy modulů, typy parametrů, názvy parametrů, hodnoty parametrů, čísla řádků a posuny bajtů) můžete nastavit kliknutím pravým tlačítkem myši v okně zásobníku volání.

Modré zvýraznění kolem grafického pole označuje, že aktuální vlákno je součástí tohoto pole. Aktuální vlákno je také označeno tučným zásobníkovým rámcem ve vyskakovacím okně. Pokud dvakrát kliknete na hlavní vlákno v okně Vlákna, můžete sledovat, že šipka zvýraznění v okně Paralelní zásobníky se odpovídajícím způsobem přesune.

Snímek obrazovky se zvýrazněným hlavním vláknem v okně Paralelní zásobníky

Zvýrazněné hlavní vlákno v okně Paralelní zásobníky

Pokračujte v provádění až do druhého bodu přerušení

Pokud chcete pokračovat v provádění, dokud nebude zasažen druhý bod přerušení, vyberte v nabídce Ladění možnost Pokračovat. Následující obrázek znázorňuje strom vlákna na druhém přerušení.

Snímek obrazovky z okna Paralelní zásobníky, které zobrazuje mnoho větví

Okno Paralelní zásobníky, které zobrazuje mnoho větví

Na prvním bodu zlomu se všechna čtyři vlákna přepnula z metod S.A do S.B a S.C. Tyto informace jsou stále viditelné v okně Paralelní zásobníky , ale čtyři vlákna pokročila dále. Jeden z nich pokračoval do S.D a pak S.E. Další pokračoval do S.F, S.G a S.H. Dva další pokračovali do S.I a S.J a odsud jeden z nich šel do S.K a druhý pokračoval do externího kódu ne uživatele.

Když najedete myší na snímky zásobníku, zobrazí se identifikátory vláken a další podrobnosti snímků. Modré zvýraznění označuje aktuální vlákno a žlutá šipka označuje aktivní rámeček zásobníku aktuálního vlákna.

Když najedete myší na záhlaví pole, například 1 vlákno nebo 2 vlákna, zobrazí se ID vláken. Když najedete myší na snímky zásobníku, zobrazí se identifikátory vláken a další podrobnosti snímků. Modré zvýraznění označuje aktuální vlákno a žlutá šipka označuje aktivní rámeček zásobníku aktuálního vlákna.

Ikona vláken (propletené čáry) označuje aktivní zásobníkové rámce neaktuálních vláken. V okně Zásobník volání poklikejte na S.B a přepněte rámce. Okno Paralelní zásobníky označuje aktuální zásobníkový rámec aktuálního vlákna pomocí ikony se zakřivenou šipkou.

Poznámka:

Popis všech ikon v okně Paralelní zásobníky najdete v části Použití okna Paralelní zásobníky.

V okně Vlákna přepněte mezi vlákny a všimněte si, že se zobrazení v okně Paralelní zásobníky aktualizuje.

Pomocí kontextové nabídky v okně Paralelní zásobníky můžete přepnout na jiné vlákno nebo na jiný rámec jiného vlákna. Klikněte například pravým tlačítkem myši na S. J., najeďte na Přepnout na rámeček a poté vyberte příkaz.

Snímek obrazovky s cestou provádění paralelních zásobníků

Paralelní zásobníky: cesta provádění

Klikněte pravým tlačítkem myši S.C a přejděte na přepínač Na rámec. Jeden z příkazů má zaškrtávací značku, která indikuje rámec zásobníku aktuálního vlákna. Můžete přepnout na tento rámec stejného vlákna (pouze zakřivená šipka se přesune) nebo můžete přepnout na druhé vlákno (modré zvýraznění se také přesune). Následující obrázek znázorňuje podnabídku.

Snímek obrazovky s nabídkou Stacks s 2 možnostmi v jazyce C, zatímco J je aktuální

Nabídka Stacks s 2 možnostmi v jazyce C, zatímco J je aktuální

Pokud je kontext metody přidružený pouze k jednomu rámečku zásobníku, záhlaví panelu zobrazí 1 vlákno a můžete na něj přepnout dvojitým kliknutím. Pokud dvakrát kliknete na kontext metody, který má přidružený více než 1 rámec, nabídka se automaticky zobrazí. Při najetí myší na kontexty metody si všimněte černého trojúhelníku vpravo. Kliknutím na tento trojúhelník se zobrazí také místní nabídka.

U velkých aplikací, které mají mnoho vláken, se můžete zaměřit jenom na podmnožinu vláken. Okno Paralelní zásobníky může zobrazovat zásobníky volání pouze pro označená vlákna. Pokud chcete označit vlákna příznakem, použijte kontextovou nabídku nebo první buňku vlákna.

Na panelu nástrojů vyberte tlačítko Zobrazit pouze označené vedle seznamu.

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

Okno Paralelní zásobníky a popis

Nyní se v okně Paralelní zásobníky zobrazují pouze označená vlákna.

Pokračovat v provádění až do třetího bodu přerušení

  1. Chcete-li pokračovat v provádění až do třetí zarážky, vyberte v nabídce Ladění možnost Pokračovat.

    Pokud je více vláken ve stejné metodě, ale metoda nebyla na začátku zásobníku volání, metoda se zobrazí v různých polích. Příklad aktuálního bodu zlomu je S.L, které má tři vlákna a zobrazuje se ve třech krabicích. Poklikejte na S.L.

    Snímek obrazovky s cestou provádění v okně Paralelní zásobníky

    Cesta spuštění v okně Paralelní Stohy

    Všimněte si, že S.L je zmíněno tučně v dalších dvou polích, takže můžete snadno vidět, kde se nachází. Pokud chcete zjistit, které rámce volají do S.L a které rámce volá, vyberte na panelu nástrojů tlačítko Přepnout zobrazení metody . Následující obrázek znázorňuje zobrazení metody okna Paralelní zásobníky .

    Snímek obrazovky se zobrazením Metody v okně Paralelní zásobníky

    Zobrazení metody v okně '

    Všimněte si, jak se diagram zaměřil na vybranou metodu a umístil ji do jejího vlastního pole uprostřed zobrazení. Volaní a volající se zobrazí nahoře a dole. Chcete-li tento režim opustit, znovu vyberte tlačítko Přepnout zobrazení metody .

    Nabídka zkratek okna Paralelní zásobníky obsahuje také následující položky.

    • Šestnáctkové zobrazení přepíná čísla v popiscích mezi desetinným a šestnáctkovým formátem.

    • Nastavení symbolů otevře příslušná dialogová okna.

    • Zobrazení vláken ve zdroji přepíná zobrazení značek vláken ve zdrojovém kódu, které zobrazuje umístění vláken ve zdrojovém kódu.

    • Zobrazit externí kód zobrazí všechny rámce, i když nejsou v uživatelském kódu. Zkuste to a podívejte se, jak se diagram rozšiřuje, aby vytvořil prostor pro další rámce (které mohou být ztlumené, protože pro ně nemáte symboly).

  2. V okně Paralelní zásobníky se ujistěte, že je na panelu nástrojů zapnuté tlačítko Automatické posouvání na aktuální rámec zásobníku .

    Pokud máte velké diagramy a přejdete na další zarážku, možná budete chtít, aby se zobrazení automaticky posouvalo na aktivní zásobníkový rámec aktuálního vlákna; to znamená toho vlákna, které jako první narazilo na zarážku.

  3. Než budete pokračovat, v okně Paralelní zásobníky se posuňte úplně doleva a úplně dolů.

Pokračujte v provádění až do čtvrtého bodu přerušení

  1. Pokud chcete pokračovat v provádění, dokud nebude nalezena čtvrtá zarážka, vyberte v nabídce Ladění možnost Pokračovat.

    Všimněte si, jak se zobrazení automaticky posunulo na místo. Přepněte vlákna v okně Vlákna nebo přepněte rámce zásobníku v okně Zásobník volání a pozorujte, jak se zobrazení vždy automaticky posouvá na správný rámec. Vypněte možnost Automatické posouvání na aktuální rámec nástroje a zobrazte rozdíl.

    Zobrazení ptačí perspektivy také pomáhá s velkými diagramy v okně Paralelní zásobníky . Ve výchozím nastavení je ptačí perspektiva zapnutá . Můžete ho ale přepnout kliknutím na tlačítko mezi posuvníky v pravém dolním rohu okna, jak je znázorněno na následujícím obrázku.

    Snímek obrazovky s pohledem z ptačí perspektivy v okně Paralelní zásobníky.

    Pohled z ptačí perspektivy v okně 'Paralelní zásobníky'

    V zobrazení ptačí perspektivy můžete obdélník přesunout a rychle se posouvat kolem diagramu.

    Dalším způsobem, jak diagram přesunout v libovolném směru, je vybrat prázdnou oblast diagramu a přetáhnout ho tam, kde ho chcete.

    Pokud chcete diagram přiblížit nebo oddálit, stiskněte a podržte klávesu CTRL a pohybujte kolečkem myši. Případně vyberte tlačítko Lupa na panelu nástrojů a pak použijte nástroj Lupa.

    Zásobníky můžete zobrazit také ve směru shora dolů místo zdola nahoru, a to tak, že kliknete na nabídku Nástroje, vyberete Možnosti a pak vyberte nebo zrušte možnost v uzlu Ladění.

  2. Než budete pokračovat, v nabídce Ladění vyberte Zastavit ladění, a tím ukončíte provádění.

Použití okna Paralelní úlohy a zobrazení úkolů v okně Paralelní zásobníky

Doporučujeme, abyste před pokračováním dokončili předchozí postupy.

Restartujte aplikaci, dokud není dosažen první bod přerušení.

  1. V nabídce Ladění vyberte Spustit ladění a počkejte na dosažení první zarážky.

  2. V nabídce Ladění přejděte na Windows a pak vyberte Vlákna. Ukotvěte okno Vlákna do spodní části sady Visual Studio.

  3. V nabídce Ladění přejděte na Windows a vyberte Zásobník volání. Ukotvěte okno Zásobník volání v dolní části okna Visual Studio.

  4. Poklikejte na vlákno v okně Vlákna , aby bylo aktuální. Aktuální vlákna mají žlutou šipku. Když změníte aktuální vlákno, ostatní okna se aktualizují. Dále prozkoumáme úkoly.

  5. V nabídce Ladění přejděte na Windows a pak vyberte Úkoly. Následující obrázek znázorňuje okno Úkoly .

    Snímek obrazovky se čtyřmi spuštěnými úkoly v okně Úkoly

    Čtyři spuštěné úkoly v okně Úkoly

    Pro každou právě běžící úlohu můžete přečíst její ID, které je vráceno stejnou pojmenovanou vlastností, ID a název vlákna, které ji spouští, a její umístění (při najetí myší se zobrazí tooltip s úplným zásobníkem volání). Také pod sloupcem Task můžete vidět metodu, která byla předána do úkolu; jinými slovy, výchozí bod.

    Můžete řadit libovolný sloupec. Všimněte si glyf řazení, který označuje sloupec a směr řazení. Sloupce můžete také změnit tak, že je přetáhnete doleva nebo doprava.

    Žlutá šipka označuje aktuální úkol. Úkoly můžete přepnout dvojitým kliknutím na úkol nebo pomocí místní nabídky. Když přepnete úkoly, podkladové vlákno se změní na aktuální a ostatní okna se aktualizují.

    Když ručně přepnete z jednoho úkolu na jiný, obrys šipky označuje aktuální kontext ladicího programu pro neaktuální úlohu.

    Když ručně přepnete z jednoho úkolu na jiný, žlutá šipka se přesune, zatímco bílá šipka stále ukazuje na úkol, kvůli kterému se ladicí program zastavil.

Pokračujte v provádění až do druhého bodu přerušení

Pokud chcete pokračovat v provádění, dokud nebude zasažen druhý bod přerušení, vyberte v nabídce Ladění možnost Pokračovat.

Dříve se ve sloupci Stav zobrazily všechny úkoly jako Aktivní, ale teď jsou dva úkoly blokované. Úkoly je možné blokovat z mnoha různých důvodů. Ve sloupci Stav najeďte myší na čekající úkol, abyste se dozvěděli, proč je blokovaný. Například na následujícím obrázku čeká úkol 11 na úkol 12.

Snímek obrazovky se dvěma čekající úkoly v okně Úkoly

Dříve se ve sloupci Stav zobrazily všechny úkoly jako Aktivní, ale teď jsou dva úkoly blokované. Úkoly je možné blokovat z mnoha různých důvodů. Ve sloupci Stav najeďte myší na čekající úkol, abyste se dozvěděli, proč je blokovaný. Například na následujícím obrázku úkol 4 čeká na úkol 5.

Dva čekající úkoly v okně Úkoly

Úkol 4 zase čeká na monitor vlastněný vláknem přiřazeným k úkolu 2. (Klikněte pravým tlačítkem myši na řádek záhlaví a zvolte Sloupce.>Přiřazení vlákna pro zobrazení hodnoty přiřazení vlákna pro úkol 2).

Čekání na úkol a nápověda v okně Úkoly

Úkol můžete označit příznakem kliknutím na příznak v prvním sloupci okna Úkoly .

Pomocí označení můžete sledovat úlohy mezi různými zarážkami v rámci stejného ladění nebo filtrovat pro úlohy, pro které jsou zobrazeny zásobníky volání v okně Paralelní zásobníky.

Když jste použili okno Paralelní zásobníky dříve, zobrazili jste vlákna aplikace. Znovu si prohlédněte okno Paralelní zásobníky , ale tentokrát si prohlédněte úlohy aplikace. Uděláte to tak, že v poli vlevo nahoře vyberete Úkoly . Následující obrázek znázorňuje zobrazení Úkolů.

Snímek obrazovky zobrazení Úkolů v okně Paralelní zásobníky

Zobrazení úkolů v okně Paralelní zásobníky

Vlákna, která neprovádějí žádné úlohy, se nezobrazují v panelu úloh v okně Paralelní zásobníky. Pro vlákna, která vykonávají úlohy, jsou některé rámce zásobníku, jež nejsou související s úlohami, odfiltrovány odshora a zdola zásobníku.

Znovu zobrazte okno Úkoly . Klikněte pravým tlačítkem myši na záhlaví libovolného sloupce, čímž zobrazíte místní nabídku pro sloupec.

K přidání nebo odebrání sloupců můžete použít místní nabídku. Například sloupec AppDomain není vybraný; proto se v seznamu nezobrazuje. Vyberte nadřazený objekt. Sloupec Nadřazený se zobrazuje bez hodnot pro všechny čtyři úkoly.

Pokračovat v provádění až do třetího bodu přerušení

Chcete-li pokračovat v provádění až do třetí zarážky, vyberte v nabídce Ladění možnost Pokračovat.

Snímek obrazovky s pohledem na nadřazené a podřízené v okně úkolů.

V tomto příkladu spuštění si všimněte, že úkol 11 a úkol 12 běží na stejném vlákně (zobrazte sloupec Přiřazení vlákna, pokud je skrytý). Tyto informace se nezobrazují v okně Vlákna, zde je další výhoda okna Úlohy. Pokud to chcete potvrdit, podívejte se do okna Paralelní zásobníky . Ujistěte se, že si prohlížíte Úkoly. Úkoly 11 a 12 najdete naskenováním popisků v okně Parallel Stacks.

Zobrazení úloh v okně Paralelní zásobníky

Nový úkol, úkol 5, je nyní spuštěný a úkol 4 teď čeká. Důvod můžete zjistit tak, že v okně Stav najedete myší na čekající úkol. Ve sloupci Nadřazený si všimněte, že úkol 4 je rodičem úkolu 5.

Pokud chcete lépe vizualizovat vztah nadřazený-podřízený, klikněte pravým tlačítkem myši na řádek záhlaví sloupce a vyberte nadřazené podřízené zobrazení. Měl by se zobrazit následující obrázek.

Hierarchické zobrazení v okně Úkoly

Všimněte si, že úloha 4 a úkol 5 běží ve stejném vlákně (pokud je skrytý, zobrazte sloupec Přiřazení vlákna ). Tyto informace se nezobrazují v okně Vlákna, zde je další výhoda okna Úlohy. Pokud to chcete potvrdit, podívejte se do okna Paralelní zásobníky . Ujistěte se, že si prohlížíte Úkoly. Úkoly 4 a 5 vyhledejte poklikáním v okně Úkoly . Když to uděláte, aktualizuje se modré zvýraznění v okně Paralelní zásobníky . Úkoly 4 a 5 můžete vyhledat také tak, že v okně Paralelní zásobníky prohlédnete si nápovědy.

Zobrazení úloh v okně Paralelní zásobníky

V okně Paralelní zásobníky klikněte pravým tlačítkem na S.P a pak vyberte Přejít na vlákno. Okno se přepne do zobrazení vláken a odpovídající rámec je v zobrazení. Obě úlohy můžete zobrazit ve stejném vlákně.

Zvýrazněné vlákno v zobrazení vláken

Toto je další výhodou zobrazení úloh v okně Paralelní zásobníky v porovnání s oknem Vlákna .

Pokračujte v provádění až do čtvrtého bodu přerušení

Chcete-li pokračovat v provádění až do třetí zarážky, vyberte v nabídce Ladění možnost Pokračovat. Vyberte záhlaví sloupce ID pro řazení podle ID. Měl by se zobrazit následující obrázek.

Snímek obrazovky se čtyřmi stavy úkolů v okně Paralelní zásobníky

Úkol 10 a úkol 11 teď čekají na sebe a jsou blokované. Nyní je naplánováno také několik nových úkolů. Naplánované úkoly jsou úkoly, které byly spuštěny v kódu, ale ještě nebyly spuštěny. Sloupce Umístění a Přiřazení vláken proto zobrazují výchozí zprávy nebo jsou prázdné.

Čtyři stavy úkolů v okně Paralelní zásobníky

Vzhledem k tomu, že úkol 5 byl dokončen, už se nezobrazuje. Pokud tomu tak ve vašem počítači není a zásek se nezobrazí, postupujte o jeden krok stisknutím klávesy F11.

Úkol 3 a úkol 4 teď čekají na sebe a jsou blokované. K dispozici je také 5 nových úkolů, které jsou podřízené úkolu 2 a nyní jsou naplánované. Naplánované úkoly jsou úkoly, které byly spuštěny v kódu, ale ještě nebyly spuštěny. Sloupce Umístění a Přiřazení vláken jsou proto prázdné.

Znovu zobrazte okno Paralelní zásobníky . Záhlaví každého pole obsahuje popis, který zobrazuje ID a názvy vláken. Přepněte do zobrazení úkolů v okně Paralelní zásobníky . Najeďte myší na záhlaví, abyste viděli ID a název úkolu a stav úkolu, jak je znázorněno na následujícím obrázku.

Popis záhlaví v okně Paralelní zásobníky

Úkoly můžete seskupit podle sloupce. V okně Úkoly klikněte pravým tlačítkem myši na záhlaví sloupce Stav a pak vyberte Seskupovat podle stavu. Následující obrázek znázorňuje okno Úkoly seskupené podle stavu.

Snímek obrazovky se seskupenými úkoly v okně Úkoly

Seskupené úkoly v okně Úkoly

Můžete také seskupit podle libovolného jiného sloupce. Seskupením úkolů se můžete zaměřit na podmnožinu úkolů. Každá sbalitelná skupina má počet položek, které jsou seskupené dohromady.

Poslední funkcí okna Úkoly, kterou je třeba prozkoumat, je místní nabídka, která se zobrazí po kliknutí pravým tlačítkem myši na úkol.

Místní nabídka zobrazuje různé příkazy v závislosti na stavu úkolu. Příkazy můžou zahrnovat kopírovat, vybrat vše, šestnáctkové zobrazení, přepnout na úlohu, zmrazit přiřazené vlákno, zmrazit všechna vlákna kromě tohoto, rozmrazit přiřazené vlákno a označit.

Můžete ukotvit základní vlákno úlohy nebo úkolů nebo můžete ukotvit všechna vlákna kromě přiřazeného vlákna. Zmrazené vlákno je znázorněno v okně Úkoly stejně jako v okně Vlákna modrou ikonou pozastavení.

Shrnutí

Tento názorný postup předvedl ladicí okna paralelní úlohy a paralelní zásobníky. Tato okna použijte v reálných projektech, které používají vícevláknový kód. Můžete prozkoumat paralelní kód napsaný v jazyce C++, C# nebo Visual Basic.