Sdílet prostřednictvím


Návod: Ladění paralelní aplikace

Tento názorný postup ukazuje, jak použít Paralelní úlohy a Paralelní hromádky ladit paralelní aplikacev systému windows.Tato okna vám pomohou porozumět a ověřit chování za běhu kódu, který používá Task Parallel Library (TPL) nebo Concurrency Runtime.Tento návod obsahuje ukázkový kód, který obsahuje předdefinované zarážky.Po přerušení kód, návod ukazuje, jak použít Paralelní úlohy a Paralelní hromádky windows ji.

Tento návod je určena uživatelům tyto úkoly:

  • Jak zobrazit zásobníky volání všechny podprocesy v jednom zobrazení.

  • Jak zobrazit seznam System.Threading.Tasks.Task instance, které jsou vytvořeny v aplikace.

  • Jak zobrazit skutečné volání hromádky úkolů namísto podprocesů.

  • Jak přejít z kódu Paralelní úlohy a Paralelní hromádky windows.

  • Jak odolat měřítku prostřednictvím seskupení, zvětšení a další související funkce systému windows.

Požadavky

Tento postup předpokládá, že Pouze můj kód je povolena.Na Nástroje nabídkaklepněte na Možnosti, rozbalit ladění uzlu, vyberte Obecnéa pak vyberte Pouze můj kód (pouze spravované). Pokud tuto funkce, můžete pomocí tohoto postupu, ale výsledky mohou lišit z vzorů.

C# vzorku

Pokud používáte ukázkové C#, tento návod, také předpokládá, že externí kód je skrytý.Chcete-li přepnout zda externí kód je zobrazen, klepněte pravým tlačítkem myši název hlavička tabulky Zásobník volání oknoa pak vyberte nebo zrušte Zobrazit externí kód. Pokud tuto funkce, můžete pomocí tohoto postupu, ale výsledky mohou lišit z vzorů.

Ukázka C++

Pokud používáte ukázkové C++, odkazy na externí kód v tomto tématu můžete ignorovat.Externí kód se vztahuje pouze na vzorku C#.

Ilustrace

Ilustrace v tomto tématu zaznamenány systémem čtyřjádrový vzorku C#.Ačkoli ostatní konfigurace můžete použít k provedení tohoto postupu, ilustrace, může lišit od zobrazené v počítači.

Vytvoření projektu vzorku

Ukázkový kód v tomto návodu je aplikace , která nemá žádnou.cíl je pouze vědět, jak pomocí nástroje systému windows ladit paralelní aplikace.

vytvořit ukázkový projekt

  1. Visual Studiona soubor nabídkapřejděte na Nový a klepněte na tlačítko projektu.

  2. V Nainstalované šablonypodoknovyberte buď Visual C#, Visual Basicnebo Visual C++. Spravované jazyků zajistit, aby .NET Framework 4 se zobrazí v poli framework.

  3. Vyberte Aplikace konzoly a klepněte na tlačítko OK.Zůstávají v ladění konfigurace, což je výchozí.

  4. Otevřete soubor cpp, .cs nebo VB kód v projekt.Odstranění jeho obsahu vytvořit soubor prázdný kód.

  5. Vložte následující kód zvoleného jazyka do souboru prázdný kód.

Imports System
Imports System.Threading
Imports System.Threading.Tasks
Imports System.Diagnostics

Module S

  Sub Main()

    pcount = Environment.ProcessorCount
    Console.WriteLine("Proc count = " + pcount.ToString())
    ThreadPool.SetMinThreads(4, -1)
    ThreadPool.SetMaxThreads(4, -1)

    t1 = New Task(AddressOf A, 1)
    t2 = New Task(AddressOf A, 2)
    t3 = New Task(AddressOf A, 3)
    t4 = New Task(AddressOf 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()
  End Sub 
  Sub A(ByVal o As Object)
    B(o)
  End Sub 
  Sub B(ByVal o As Object)
    C(o)
  End Sub 
  Sub C(ByVal o As Object)

    Dim temp As Integer = o

    Interlocked.Increment(aa)
    While (aa < 4)
    End While 

    If (temp = 1) Then 
      ' BP1 - all tasks in C
      Debugger.Break()
      waitFor1 = False 
    Else 
      While (waitFor1)
      End While 
    End If 
    Select Case temp
      Case 1
        D(o)
      Case 2
        F(o)
      Case 3, 4
        I(o)
      Case Else
        Debug.Assert(False, "fool")
    End Select 
  End Sub 
  Sub D(ByVal o As Object)
    E(o)
  End Sub 
  Sub E(ByVal o As Object)
    ' break here at the same time as H and K 
    While (bb < 2)
    End While 
    'BP2 - 1 in E, 2 in H, 3 in J, 4 in K
    Debugger.Break()
    Interlocked.Increment(bb)

    'after
    L(o)
  End Sub 
  Sub F(ByVal o As Object)
    G(o)
  End Sub 
  Sub G(ByVal o As Object)
    H(o)
  End Sub 
  Sub H(ByVal o As Object)
    ' break here at the same time as E and K
    Interlocked.Increment(bb)
    Monitor.Enter(mylock)
    While (bb < 3)
    End While
    Monitor.Exit(mylock)

    'after
    L(o)
  End Sub 
  Sub I(ByVal o As Object)
    J(o)
  End Sub 
  Sub J(ByVal o As Object)

    Dim temp2 As Integer = o

    Select Case temp2
      Case 3
        t4.Wait()
      Case 4
        K(o)
      Case Else
        Debug.Assert(False, "fool2")
    End Select 
  End Sub 
  Sub K(ByVal o As Object)
    ' break here at the same time as E and H
    Interlocked.Increment(bb)
    Monitor.Enter(mylock)
    While (bb < 3)
    End While
    Monitor.Exit(mylock)

    'after
    L(o)
  End Sub 
  Sub L(ByVal oo As Object)
    Dim temp3 As Integer = oo

    Select Case temp3
      Case 1
        M(oo)
      Case 2
        N(oo)
      Case 4
        O(oo)
      Case Else
        Debug.Assert(False, "fool3")
    End Select 
  End Sub 
  Sub M(ByVal o As Object)
    ' breaks here at the same time as N and Q
    Interlocked.Increment(cc)
    While (cc < 3)
    End While 

    'BP3 - 1 in M, 2 in N, 3 still in J, 4 in O, 5 in Q
    Debugger.Break()
    Interlocked.Increment(cc)
    While (True)
      Thread.Sleep(500) '  for ever
    End While 
  End Sub 
  Sub N(ByVal o As Object)
    ' breaks here at the same time as M and Q
    Interlocked.Increment(cc)
    While (cc < 4)
    End While
    R(o)
  End Sub 
  Sub O(ByVal o As Object)
    Dim t5 As Task = Task.Factory.StartNew(AddressOf P, TaskCreationOptions.AttachedToParent)
    t5.Wait()
    R(o)
  End Sub 
  Sub P()
    Console.WriteLine("t5 runs " + Task.CurrentId.ToString())
    Q()
  End Sub 
  Sub Q()
    ' breaks here at the same time as N and M
    Interlocked.Increment(cc)
    While (cc < 4)
    End While 
    ' task 5 dies here freeing task 4 (its parent)
    Console.WriteLine("t5 dies " + Task.CurrentId.ToString())
    waitFor5 = False 
  End Sub 
  Sub R(ByVal o As Object)
    If (o = 2) Then 
      ' wait for task5 to die 
      While waitFor5
      End While 

      '//spin up all procs 
      Dim i As Integer 
      For i = 0 To pcount - 4 - 1

        Dim t As Task = Task.Factory.StartNew(Sub()
                                                While True 

                                                End While 
                                              End Sub)
        Console.WriteLine("Started task " + t.Id.ToString())
      Next

      Task.Factory.StartNew(AddressOf T, i + 1 + 5, TaskCreationOptions.AttachedToParent) ' //scheduled
      Task.Factory.StartNew(AddressOf T, i + 2 + 5, TaskCreationOptions.AttachedToParent) ' //scheduled
      Task.Factory.StartNew(AddressOf T, i + 3 + 5, TaskCreationOptions.AttachedToParent) ' //scheduled
      Task.Factory.StartNew(AddressOf T, i + 4 + 5, TaskCreationOptions.AttachedToParent) ' //scheduled
      Task.Factory.StartNew(AddressOf 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(o = 4)
      t3.Wait()
    End If 
  End Sub 
  Sub T(ByVal o As Object)
    Console.WriteLine("Scheduled run " + Task.CurrentId.ToString())
  End Sub 
  Private t1, t2, t3, t4 As Task
  Private aa As Integer = 0
  Private bb As Integer = 0
  Private cc As Integer = 0
  Private waitFor1 As Boolean = True 
  Private waitFor5 As Boolean = True 
  Private pcount As Integer 
  Private mylock As New S2()
End Module 

Public Class S2

End Class
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();
}
#include "stdafx.h"
#include <windows.h>
#include <iostream>
#include <ppl.h>
#include <agents.h>
#include <stdio.h>
#include <concrtrm.h>
#include <vector>

CRITICAL_SECTION cs;

using namespace ::std;
using namespace ::std::tr1;
using namespace ::Concurrency;
task_group task4;
task_group task3;
task_group task2;

volatile long aa = 0;
volatile long bb = 0;
volatile long cc = 0;
static bool waitFor1 = true;
static bool waitFor5 = true;

#pragma optimize("", off)
void Spin()
{
   for(int i=0;i<50*50000;++i);
}
#pragma optimize("",on)

template<class Func>
class RunFunc
{
   Func& m_Func;
   int m_o;
public:
   RunFunc(Func func,int o):m_Func(func),m_o(o){

   };
   void operator()()const{
      m_Func(m_o);
   };
};

void T(int o)
{
   cout << "Scheduled run \n";

};

void R(int o)
{
   if (o == 2)
   {
      while (waitFor5) { ;}
      Spin();

      //use up all processors but 4 by scheduling 4 non-terminating tasks. 
      int numProcsToBurn = GetProcessorCount() - 4;
      int i;
      vector<call<int>*> tasks;
      for (i = 0; i <  numProcsToBurn; i++)
      {
         tasks.push_back(new call<int>([](int i){while(true)Spin();}));
         asend(tasks[i],1);
         cout << "Started task  \n";
      }

      task_handle<RunFunc<decltype(T)>> t6(RunFunc<decltype(T)>(T,i + 1 + 5));
      task_handle<RunFunc<decltype(T)>> t7(RunFunc<decltype(T)>(T,i + 2 + 5));
      task_handle<RunFunc<decltype(T)>> t8(RunFunc<decltype(T)>(T,i + 3 + 5));
      task_handle<RunFunc<decltype(T)>> t9(RunFunc<decltype(T)>(T,i + 4 + 5));
      task_handle<RunFunc<decltype(T)>> t10(RunFunc<decltype(T)>(T,i + 5 + 5));
      task2.run(t6);
      task2.run(t7);
      task2.run(t8);
      task2.run(t9);
      task2.run(t10);

      //BP4 - 1 in M, 2 in R, 3 in J, 4 in R, 5 died   
      DebugBreak();
   }
   else
   {
      if (o!=4)
         throw;

      task3.wait();      
   }
};

void Q()
{
   // breaks here at the same time as N and M
   InterlockedIncrement(& cc);
   while (cc < 4)
   {
      ;
   }
   // task 5 dies here freeing task 4 (its parent)
   cout << "t5 dies\n";
   waitFor5 = false;
};

void P()
{
   cout << "t5 runs\n";
   Q();
};

void O(int o)
{   
   task_group t5;
   t5.run(&P);
   t5.wait();
   R(o);
};

void N(int o)
{
   // breaks here at the same time as M and Q
   InterlockedIncrement(&cc);
   while (cc < 4)
   {
      ;
   }
   R(o);
};

void M(int o)
{
   // breaks here at the same time as N and Q
   InterlockedIncrement(&cc);
   while (cc < 3)
   {
      ;
   }
   //BP3 - 1 in M, 2 in N, 3 still in J, 4 in O, 5 in Q
   DebugBreak();
   InterlockedIncrement(&cc);
   while (true)
      Sleep(500); // for ever
};

void L(int oo)
{
   int temp3 = oo;

   switch (temp3)
   {
   case 1:
      M(oo);
      break;
   case 2:
      N(oo);
      break;
   case 4:
      O(oo);
      break;
   default:
      throw; //fool3 
      break;
   }
}
void K(int o)
{
   // break here at the same time as E and H
   InterlockedIncrement(&bb);
   EnterCriticalSection(&cs);
   while (bb < 3)
   {
      ;
   }
   LeaveCriticalSection(&cs);
   Spin();

   //after
   L(o);
}
void J(int o)
{
   int temp2 = o;

   switch (temp2)
   {
   case 3:
      task4.wait();
      break;
   case 4:
      K(o);
      break;
   default:
      throw; //fool2 
      break;
   }
}
static void I(int o)
{
   J(o);
}
static void H(int o)
{
   // break here at the same time as E and K
   InterlockedIncrement(&bb);
   EnterCriticalSection(&cs);
   while (bb < 3)
   {
      ;
   }
   LeaveCriticalSection(&cs);
   Spin();

   //after
   L(o);
}
static void G(int o)
{
   H(o);
}
static void F(int o)
{
   G(o);
}

static void E(int 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   
   Spin(); // for native case only
   DebugBreak();
   InterlockedIncrement(&bb);

   //after
   L(o);

}

static void D(int o)
{
   E(o);
}

static void C(int o)
{
   int temp = o;

   InterlockedIncrement(&aa);
   while (aa < 4)
   {
      ;
   }

   if (temp == 1)
   {
      // BP1 - all tasks in C   
      DebugBreak();
      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:
      throw; //fool 
      break;
   }
}
static void B(int o)
{
   C(o);
}

void A(int o)
{
   B(o);
}
int main()
{
   InitializeCriticalSection(&cs);

   task_group tasks;
   task_handle<RunFunc<decltype(A)>> t1(RunFunc<decltype(A)>(A,1));
   tasks.run(t1);
   task_handle<RunFunc<decltype(A)>> t2(RunFunc<decltype(A)>(A,2));
   task2.run(t2);
   task_handle<RunFunc<decltype(A)>> t3(RunFunc<decltype(A)>(A,3));
   task3.run(t3);
   task_handle<RunFunc<decltype(A)>> t4(RunFunc<decltype(A)>(A,4));
   task4.run(t4);

   getchar();
   return 1;
}
  1. V nabídce Soubor klikněte na příkaz Uložit vše.

  2. Na sestavení nabídka, klepněte na tlačítko Znovu vytvořit řešení.

    Jsou čtyři volání na Debugger.Break (DebugBreak ve vzorku C++), proto není nutné vložení zarážky; Přerušit ladění až čtyřikrát způsobí právě spuštěnou aplikace .

Pomocí okna paralelní hromádky: zobrazení podprocesů

V nabídce Ladit klikněte na příkaz Spustit ladění.Počkejte první zarážka být přístupů.

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

  1. Na ladění nabídkapřejděte na Windows a klepněte na tlačítko vlákna. Ukotvit vláknaokno v dolní části Visual Studio.

  2. Na ladění nabídkapřejděte na Windows a klepněte na tlačítko Zásobník volání. Ukotvit Zásobník voláníokno v dolní Visual Studio.

  3. Poklepejte na vlákno v vláknaokno aktuální. Aktuální podprocesy mít žlutou šipku.Pokud změníte aktuální vlákno, jeho zásobník volání je zobrazen v Zásobník voláníokno.

Přezkoumat paralelní hromádky okno

  • Na ladění nabídkapřejděte na Windows a klepněte na tlačítko Paralelní hromádky. Ujistěte se, že vlákna je vybrán v okně v levém horním rohu.

    Pomocí Paralelní hromádky oknomůžete zobrazit více zásobníky volání současně v jednom zobrazení.Následující obrázek ukazuje Paralelní hromádky okno Zásobník voláníokno.

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

    zásobník volání hlavní vlákno se zobrazí v jednom poli a zásobníky volání pro čtyři podprocesy jsou seskupeny do jiného pole.Čtyři podprocesy jsou seskupeny jejich zásobníku rámečky sdílejí stejnou metoda kontextech; To znamená, že jsou ve stejné metody: A, B, a C.Zobrazení ID vlákno a názvy podprocesů, které sdílejí stejné pole ukazatel myši nad hlavička (4 podprocesů).Aktuální vlákno je zobrazena tučně, jak je znázorněno na následujícím obrázku.

    Popis tlačítka, který se zobrazuje názvy a ID vlákna

    Žlutá šipka označuje aktivní zásobník snímek aktuálního vlákno.Chcete-li získat další informace, umístěte ukazatel myši nad ní

    Popis tlačítka na aktivní zásobníku

    Můžete nastavit, kolik podrobností zobrazit zásobník rámců (Názvy, Typy parametrů, Názvy parametrů, Hodnoty parametru, Čísla řádků a Kompenzuje bajt) klepnutím pravým tlačítkem myši Zásobník voláníokno.

    Modré zvýraznění kolem pole znamená, že aktuální vlákno část daného pole.Aktuální vlákno je také uveden tučně zásobníku snímek v popisu.Pokud poklepete na hlavní vlákno v podprocesů okno, můžete sledovat, modré zvýraznění v Paralelní hromádkyodpovídajícím způsobem přesuneokno .

    V okně paralelní zásobníky zvýrazněné hlavní vlákno

Pokračovat v provádění až do druhého zarážka

  • Spuštění pokračovat, dokud druhý zarážka přístupů, na ladění nabídka, klepněte na tlačítko Pokračovat. Následující obrázek znázorňuje vlákno strom na druhý zarážka.

    Okno Paralelní zásobníky zobrazující mnoho větve

    U první zarážkavšechny čtyři podprocesy přešel z S.A na S.B S.C metod.Informace jsou stále viditelné Paralelní hromádkyokno, ale čtyři podprocesy pokročila dále. Jeden z nich nadále S.D a pak jihovýchodníJiné S.F, S.G a S.H.Dvěma dalšími pokračování S.I a S.J a pak z nich přešel na S.K a druhé pokračování na non - externí kóduživatel .

    Například, podržte nad pole hlavička 1 vlákno nebo 2 podprocesů, viz vlákno ID podprocesy.Můžete ukazatel zásobníku rámců zobrazit ID vlákno plus dalších podrobností snímek .Modré zvýraznění označuje aktuální vlákno a žlutá šipka označuje aktivní zásobník snímek aktuálního vlákno.

    Ikona hadřík podprocesů (překrývající se modré a červené waved řádky) označují aktivní zásobník rámce fixní podprocesů.V Zásobník voláníokno, poklepejte na S.B přepnout rámců. Paralelní hromádkyokno indikuje aktuální zásobníku snímek aktuálního vlákno pomocí ikony zelené Zahnutou šipku.

    V podprocesy oknopřepínání podprocesů a že v zobrazení Paralelní hromádkyokno je aktualizován.

    Přepnout na jiný vláknonebo do jiného snímek jiný vláknopomocí zástupcenabídka v Paralelní hromádkyokno. Například S.J tlačítkem, přejděte na Přepínače do rámečkua poté klepněte na příkaz.

    Paralelní zásobníky – cesta spuštění

    Klepněte pravým tlačítkem na S.C a přejděte na Přepínače do rámečku.Jeden z příkazů má zaškrtnutí označující zásobníku snímek aktuálního vlákno.Můžete přepnout do snímek stejné vlákno (pouze zelenou šipkou přesune) nebo můžete přepnout do jiného vlákno (modré zvýraznění přesune také).Následující obrázek znázorňuje podnabídky.

    Nabídka zásobníky s 2 možnosti týkající se C při aktuální J

    metodakontext přidružen pouze jeden snímek, zobrazí pole hlavička 1 vlákno a poklepáním můžete přepnout na něj. Pokud poklepete na metoda kontext , který má více než 1 snímek s ním spojené, pak v nabídka automaticky zobrazí.Jako ukazatele kontexty metoda oznámení černý trojúhelník vpravo.Klepnutím na tento trojúhelník také zobrazí v zástupce nabídka.

    Rozsáhlých aplikací, které mají mnoho podprocesů můžete zaměřit na pouze podmnožinu podprocesů.Paralelní hromádkyokno můžete zobrazit zásobníky volání pouze pro příznakem podprocesů. Na panelu nástrojů klepněte Zobrazit pouze příznakem vedle seznam.

    Prázdný okno Paralelní zásobníky a popis tlačítka

    Další v vlákna okno označit příznakem podprocesy postupně zobrazit vzhled jejich zásobníky volání v Paralelní hromádkyokno. označit příznakem podprocesům pomocí zástupcenabídka nebo na první buňku vlákno. Klepněte Zobrazit pouze příznakem tlačítko na panelu nástrojů znovu zobrazit všechny podprocesy.

Pokračovat v provádění až třetí zarážka

  1. Spuštění pokračovat, dokud třetí zarážka přístupů, na ladění nabídka, klepněte na tlačítko Pokračovat.

    Více podprocesů jsou ve stejné metoda , ale nebyl na začátku zásobník volání metoda , metoda se zobrazí v různých oknech.Je například u aktuální zarážka S.L, který má tři podprocesů a zobrazí se ve třech polích.Poklepejte na j.

    Cesta spuštění v okně paralelní zásobníky

    Všimněte si, že je S.L do dvou polí tučně, uvidíte v opačném případě se zobrazí.Chcete-li zobrazit rámce, který volání do S.L a které rámce je volání, klepněte Přepnout zobrazení metodu tlačítko na panelu nástrojů.Následující obrázek znázorňuje metoda zobrazení Paralelní hromádky okno.

    Metoda zobrazení v okně paralelní zásobníky

    Všimněte si, jak diagram sklopí na vybrané metoda a umístí do jeho vlastní pole uprostřed zobrazení.Callees a volající se zobrazí v horní a dolní.Klepněte Přepnout zobrazení metodu tlačítko opustit tento režim.

    V zástupcenabídka Paralelní hromádkyokno obsahuje také následující další položky.

    • Hexadecimální zobrazení přepíná čísel v popiscích mezi desítkové číslo a šestnáctkovém formátu.

    • Symbol zatížení informace a Nastavení Symbol otevřený příslušných dialogových oknech.

    • Přejít do zdrojového kódu a Přejít K rozebrání navigaci v editor vybrané metoda.

    • Externí kód zobrazí všechny snímky, i když nejsou kód uživatel .Zkuste zobrazit diagram rozbalit tak, aby další snímků (které mohou být vyšedlá, protože pro ně nemáte symboly).

    Máte velkých diagramů a kroku k další zarážka, chcete zobrazit automatický posun k aktivní zásobník snímek aktuálního vlákno. je vlákno , který nejprve přístupů zarážka .V Paralelní hromádky okno, ujistěte se, že Automaticky přejít na aktuální snímek zásobníku je tlačítko na panelu nástrojů na.

    Automatické procházení v okně paralelní zásobníky

  2. Než budete pokračovat v Paralelní hromádkyokno, posunutí všech způsobem doleva a úplně dolů.

Pokračovat v provádění až čtvrtý zarážka

  1. Spuštění pokračovat, dokud čtvrtý zarážka přístupů, na ladění nabídka, klepněte na tlačítko Pokračovat.

    Oznámení o způsobu zobrazení autoscrolled na místě.Přepínání podprocesů podprocesů okno nebo přepínač zásobníku snímky Zásobník voláníokno a oznámení jak zobrazení vždy autoscrolls na správné snímek. Vypnout Automaticky přejít na aktuální snímek nástroj možnost a zobrazit rozdíl.

    Ptačí perspektivy také pomáhá s velkých diagramů v Paralelní hromádkyokno. Zobrazí Ptačí perspektivy klepnutím na tlačítko mezi posuvníky v pravém dolním rohu okno, jak je znázorněno na následujícím obrázku.

    Čase zobrazení v okně paralelní zásobníky

    obdélník , rychlý posun kolem diagramu můžete přesunout.

    Klepněte do prázdné oblast diagramu a přetáhněte ji na požadované místo je jiným způsobem přesunutí diagramu v libovolném směru.

    zvětšit z diagramu stiskněte a podržte klávesu CTRL a přesunutím kolečka myš .Případně klepněte na tlačítko Lupa na panelu nástrojů a potom pomocí nástroje Lupa.

    Zvětšený zásobníků v okno Paralelní zásobníky

    Můžete také zobrazit hromádky namísto zdola nahoru směrem shora dolů klepnutím Nástroje nabídkaklepnutím na Možnostia zaškrtněte nebo zrušte zaškrtnutí políčka ve skupinovém rámečku ladění uzel.

  2. Než budete pokračovat, na ladění nabídkaklepněte na Zastavit ladění Konec spuštění.

Pomocí okna paralelní úlohy a paralelní hromádky okno zobrazení úkoly

Doporučujeme nejdříve dokončit předchozí postupy.

Restartování aplikace až do první zarážka přístupů

  1. Na ladění nabídka, klepněte na tlačítko Spustit ladění a počkejte první zarážka být přístupů.

  2. Na ladění nabídkapřejděte na Windows a klepněte na tlačítko vlákna. Ukotvit vláknaokno v dolní části Visual Studio.

  3. Na ladění nabídkapřejděte na Windows a na Zásobník volání. Ukotvit Zásobník voláníokno v dolní Visual Studio.

  4. Poklepejte na vlákno v vláknaokno umožňuje aktuální. Aktuální podprocesy mít žlutou šipku.Pokud změníte aktuální vlákno, ostatní okna jsou aktualizovány.Dále jsme přezkoumá úkoly.

  5. Na ladění nabídkapřejděte na Windows a klepněte na tlačítko Paralelní úlohy. Následující obrázek ukazuje Paralelní úlohyokno.

    Čtyři spuštěné úlohy v okně paralelní úlohy

    Pro každý spuštěnou úlohu můžete číst jeho ID vrácené stejným názvem vlastnost, ID a název vlákno spuštěný, jeho umístění (ukazatele tohoto zobrazí popis, který byl celý zásobník volání).Také pod úkolu sloupce, zobrazí metoda předaný do úloha. jinými slovy počáteční bod.

    Můžete řadit všechny sloupce.Všimněte si řazení piktogram , který označuje sloupec a směr řazení.Můžete také změnit pořadí sloupců přetažením myší doleva nebo doprava.

    Žlutá šipka označuje aktuální úloha.Úkoly můžete přepínat poklepáním na úloha nebo pomocí zástupce nabídka.Při přepnutí úkolů podkladové vlákno se stane aktuální a ostatní okna jsou aktualizovány.

    Při ruční přepnutí z jednoho úloha do jiného, přesune žlutou šipku, ale bílá šipka zobrazuje úloha , který způsobil přerušení ladicího programu.

Pokračovat v provádění až do druhého zarážka

  • Spuštění pokračovat, dokud druhý zarážka přístupů, na ladění nabídka, klepněte na tlačítko Pokračovat.

    Dříve stav sloupec ukázalo jako spuštění všech úkolů, ale nyní dva úkoly čeká.Úkoly mohou být blokovány mnoho různých důvodů.V stav sloupec ukazatel čekání úloha se dozvíte, proč je blokován.Na následujícím obrázku je například úloha 3 čekání na úloha 4.

    Dvě čekání úlohy v okně paralelní úlohy

    Úkol 4, čeká na monitoru vlastněných vlákno přiřazen k úloha 2.

    Čekání úlohy a popis tlačítka v okně úlohy

    úloha lze označit příznakem klepnutím na tlačítko označit příznakem v prvním sloupci Paralelní úlohyokno.

    Příznaky můžete použít ke sledování úkolů mezi různé body přerušení ve stejné relaci ladění nebo filtrovat úkoly, jejichž zásobníky volání jsou uvedeny v Paralelní hromádkyokno.

    Pokud jste použili Paralelní hromádkyokno starší, zobrazit podprocesy aplikace . Zobrazení Paralelní hromádkyznovu, ale při zobrazeníokno úkoly aplikace . Provedete to vybráním úkoly do pole v levé horní části.Následující obrázek znázorňuje zobrazení úkoly.

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

    Podprocesy, které není executing aktuálně úkoly nejsou zobrazeny v zobrazení úkolů Paralelní hromádkyokno. Také pro podprocesy filtrování provést úlohy některé zásobníku snímky, které nejsou důležité pro úkoly je z horní a dolní zásobník.

    Zobrazení Paralelní úlohyokno znovu. Pravým tlačítkem myši na libovolné hlavička sloupce zobrazíte zástupce nabídka pro sloupec.

    Zobrazení nabídky v okně paralelní úlohy

    zástupcenabídka můžete přidat nebo odebrat sloupce. Například sloupec doména aplikace není vybrána; proto nejsou zobrazeny v seznamu.Klepněte na tlačítko nadřazené.Nadřazené bez hodnot pro všechny čtyři úlohy se zobrazí sloupec.

Pokračovat v provádění až třetí zarážka

  • Spuštění pokračovat, dokud třetí zarážka přístupů, na ladění nabídka, klepněte na tlačítko Pokračovat.

    Nový úloha, úloha 5, je nyní spuštěna a nyní čeká úloha 4.Uvidíte proč nastavením ukazatele myši čekající úloha v stavokno. V nadřazené sloupec, oznámení, je tento úloha 4 nadřazeného úloha 5.

    Chcete-li lépe vizualizovatpodřízenýnadřazené -relace, klepněte pravým tlačítkem myši nadřazené hlavička sloupce a potom klepněte na Zobrazení podřízená nadřazené. Měli byste vidět na následujícím obrázku.

    Nadřazený podřízené zobrazení v okně paralelní úlohy

    Všimněte si, že úloha 4 a úloha 5 jsou spuštěny ve stejném vlákno.Tyto informace nejsou zobrazeny v vláknaokno; prohlížení zde je Další výhodou Paralelní úlohyokno. Chcete-li potvrdit, zobrazení Paralelní hromádkyokno. Ujistěte se, že jsou zobrazeny úkoly.Vyhledejte poklepáním na jejich úkoly, 4 a 5 Paralelní úlohyokno. Při provedení, modré zvýraznění Paralelní hromádkyokno je aktualizován. Můžete také vyhledat úkoly, 4 a 5 skenováním na popisy Paralelní hromádkyokno.

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

    V Paralelní hromádky S.P tlačítkemoknoa klepněte na Přejít na vlákno. okno přepne do zobrazení podprocesů a odpovídající snímek je v zobrazení.Oba úkoly můžete zobrazit ve stejném vlákno.

    Zvýrazněná vlákna v zobrazení vlákna

    Toto je Další výhodou zobrazení úkolů Paralelní hromádky okno, ve srovnání s podprocesůokno.

Pokračovat v provádění až čtvrtý zarážka

  • Spuštění pokračovat, dokud třetí zarážka přístupů, na ladění nabídka, klepněte na tlačítko Pokračovat. Klepněte ID hlavička sloupce seřadit podle ID.Měli byste vidět na následujícím obrázku.

    Čtyři úloha stavy v okně paralelní zásobníky

    Protože dokončení úloha 5 již zobrazen.Pokud není případ v počítači a vzájemné zablokování není zobrazen, kroku jednou stisknutím klávesy F11.

    3 Úloh a úloha 4 nyní čeká na sebe a jsou zablokovány.Existují také 5 nových úkolů, které jsou podřízené úloha 2 a nyní naplánováno.Naplánované úlohy jsou úkoly, které byly zahájeny v kódu, ale ještě nebyl spuštěn.Proto jejich umístění a Podprocesu přiřazení sloupce jsou prázdné.

    Zobrazení Paralelní hromádkyokno znovu. hlavička každého pole obsahuje popis, který zobrazí názvy a ID vlákno .Přepněte do zobrazení úkolů Paralelní hromádkyokno. Jak ukazuje následující obrázek, umístěte ukazatel myši nad hlavička zobrazit ID úloha a název a stav úloha.

    Popis hlavičky v okno Paralelní zásobníky

    Můžete skupina úkolů podle sloupce.V Paralelní úlohy okno, klepněte pravým tlačítkem myši Stav hlavička sloupce a potom klepněte na skupiny podle stavu. Následující obrázek ukazuje Paralelní úlohyokno seskupeny podle stav.

    Seskupit v okně paralelní úlohy

    Můžete také skupina podle dalších sloupců.Seskupení úkolů můžete se zaměřit na dílčí úkoly.Počet položek, které jsou seskupeny má každý sbalitelné skupina .Můžete také rychle označit příznakem všechny položky ve skupina klepnutím příznak vpravo od tlačítka Sbalit tlačítko.

    Zásobníky seskupených v okně paralelní zásobníky

    Poslední funkce Paralelní úlohyjeokno Prozkoumat zástupcenabídka zobrazenou pravým tlačítkem myši na úloha.

    Místní nabídky v okně paralelní úlohy

    zástupcenabídka zobrazí různé příkazy, v závislosti na stav úloha. Mohou zahrnovat příkazy kopie, Vybrat vše, Hexadecimální zobrazení, přepínač úkol, Ukotvit přiřazený podproces, Ukotvit všechny podprocesy, ale tento, a Uvolnit přiřazená vlákna, a příznak.

    Můžete zakázat podkladové vlákno úlohanebo úkolů, nebo můžete zakázat všechny podprocesy kromě přiřazené.Zmrazené vlákno reprezentována Paralelní úlohy okno tak, jak je v podprocesů oknomodrá Pozastavit ikonu.

SHRNUTÍ

Tento návod prokázáno Paralelní úlohy a Paralelní hromádky ladicí program systému windows.Pomocí těchto oken na reálných projektech, používajících kódu s více podprocesy.Můžete zkoumat paralelní kód napsaný v C++, C# nebo Visual Basic.

Viz také

Úkoly

Návod: Ladění paralelní aplikace

Koncepty

Concurrency Runtime

Použití okna Paralelní zásobníky

Používání okna úloh

Další zdroje

Průvodce ladicím programem

Ladění spravovaného kódu

Paralelní programování v rozhraní .NET Framework