Share via


İzlenecek yol: Visual Studio'da Paralel Uygulamada Hata Ayıklama (C#, Visual Basic, C++)

Bu kılavuzda paralel bir uygulamada hata ayıklamak için Paralel Görevler ve Paralel Yığınlar pencerelerinin nasıl kullanılacağı gösterilmektedir. Bu pencereler, Görev Paralel Kitaplığı (TPL) veya Eşzamanlılık Çalışma Zamanı kullanan kodun çalışma zamanı davranışını anlamanıza ve doğrulamanıza yardımcı olur. Bu izlenecek yol, yerleşik kesme noktaları içeren örnek kod sağlar. Kod sonlarından sonra, izlenecek yol, Paralel Görevler ve Paralel Yığınlar pencerelerini kullanarak incelemeyi gösterir.

Bu izlenecek yol şu görevleri öğretir:

  • Tüm iş parçacıklarının çağrı yığınlarını tek bir görünümde görüntüleme.

  • Uygulamanızda oluşturulan örneklerin System.Threading.Tasks.Task listesini görüntüleme.

  • İş parçacıkları yerine görevlerin gerçek çağrı yığınlarını görüntüleme.

  • Paralel Görevler ve Paralel Yığınlar pencerelerinden koda gitme.

  • Pencerelerin gruplandırma, yakınlaştırma ve diğer ilgili özellikler aracılığıyla ölçeklendirmeyle başa çıkma şekli.

Önkoşullar

Bu kılavuzda, Yalnızca Kodum'un etkinleştirildiği varsayılır (Visual Studio'nun daha yeni sürümlerinde varsayılan olarak etkindir). Araçlar menüsünde Seçenekler'i seçin, Hata Ayıklama düğümünü genişletin, Genel'i ve ardından Yalnızca Kodumu Etkinleştir (Yalnızca yönetilen) seçeneğini belirleyin. Bu özelliği ayarlamazsanız bu kılavuzu kullanmaya devam edebilirsiniz, ancak sonuçlarınız çizimlerden farklı olabilir.

C# örneği

C# örneğini kullanırsanız, bu kılavuzda Dış Kodun gizli olduğu da varsayılır. Dış kodun görüntülenip görüntülenmeyeceğini değiştirmek için, Çağrı Yığını penceresinin Ad tablosu üst bilgisine sağ tıklayın ve Dış Kodu Göster'i seçin veya temizleyin. Bu özelliği ayarlamazsanız bu kılavuzu kullanmaya devam edebilirsiniz, ancak sonuçlarınız çizimlerden farklı olabilir.

C++ örneği

C++ örneğini kullanıyorsanız, bu makaledeki Dış Kod başvurularını yoksayabilirsiniz. Dış Kod yalnızca C# örneğine uygulanır.

İllüstrasyonlar

Bu makaledeki çizimler, C# örneğini çalıştıran dört çekirdekli bir bilgisayara kaydedilir. Bu kılavuzu tamamlamak için diğer yapılandırmaları kullanabilirsiniz, ancak çizimler bilgisayarınızda görüntülenenden farklı olabilir.

Örnek projeyi oluşturun

Bu kılavuzdaki örnek kod, hiçbir şey içermeyen bir uygulamaya yöneliktir. Alıştırmanın amacı, paralel bir uygulamada hata ayıklamak için araç pencerelerinin nasıl kullanılacağını anlamaktır.

  1. Visual Studio'yu açın ve yeni bir proje oluşturun.

    Başlangıç penceresi açık değilse Dosya>Başlangıç Penceresi'ni seçin.

    Başlangıç penceresinde Yeni proje'yi seçin.

    Başlangıç penceresinde Yeni proje oluştur'u seçin.

    Yeni proje oluştur penceresinde, arama kutusuna konsol girin veya yazın. Ardından, Dil listesinden C#, C++ veya Visual Basic'i seçin ve ardından Platform listesinden Windows'u seçin.

    Dil ve platform filtrelerini uyguladıktan sonra .NET Core veya C++ için Konsol Uygulaması'nı ve ardından İleri'yi seçin.

    Dekont

    Doğru şablonu görmüyorsanız Araçlar Araç>ve Özellik Al...'e gidin ve Visual Studio Yükleyicisi açın. .NET masaüstü geliştirme veya C++ ile masaüstü geliştirme iş yükünü ve ardından Değiştir'i seçin.

    Yeni projenizi yapılandırın penceresinde, proje adı kutusuna bir ad yazın veya varsayılan adı kullanın. Ardından İleri'yi veya Oluştur'u (hangi seçenek varsa) seçin.

    .NET Core için önerilen hedef çerçeveyi veya .NET 8'i seçin ve ardından Oluştur'u seçin.

    Yeni bir konsol projesi görüntülenir. Proje oluşturulduktan sonra bir kaynak dosya görüntülenir.

  2. Projede .cpp, .cs veya .vb kod dosyasını açın. Boş bir kod dosyası oluşturmak için içeriğini silin.

  3. Seçtiğiniz dil için aşağıdaki kodu boş kod dosyasına yapıştırın.

    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();
    }
    

Kod dosyasını güncelleştirdikten sonra değişikliklerinizi kaydedin ve çözümü oluşturun.

  1. Dosya menüsünde Tümünü Kaydet’i seçin.

  2. Derleme menüsünde Çözümü Yeniden Derle seçeneğini belirleyin.

( C++ örneğinde) için dört çağrı Debugger.BreakDebugBreak olduğuna dikkat edin. Bu nedenle kesme noktaları eklemeniz gerekmez. Uygulamanın çalıştırılması, hata ayıklayıcıda en fazla dört kez bozulmasına neden olur.

Paralel Yığınlar Penceresini Kullanma: İş Parçacıkları Görünümü

Başlamak için Hata Ayıkla menüsünde Hata Ayıklamayı Başlat'ı seçin. İlk kesme noktasına isabet edene kadar bekleyin.

Tek bir iş parçacığının çağrı yığınını görüntüleme

  1. Hata Ayıkla menüsünde Windows'un üzerine gelin ve İş Parçacıkları'nı seçin. İş Parçacıkları penceresini Visual Studio'nun en altına sabitleyin.

  2. Hata Ayıklamenüsünde Windows'un üzerine gelin ve Ardından Çağrı Yığını'nı seçin. Çağrı Yığını penceresini Visual Studio'nın alt kısmına sabitleyin.

  3. İş Parçacıkları penceresinde bir iş parçacığını geçerli hale getirmek için çift tıklayın. Geçerli iş parçacıklarının sarı bir oku vardır. Geçerli iş parçacığını değiştirdiğinizde, çağrı yığını Çağrı Yığını penceresinde görüntülenir.

Paralel Yığınlar penceresini inceleme

Hata Ayıkla menüsünde Windows'un üzerine gelin ve Paralel Yığınlar'ı seçin. Sol üst köşedeki kutuda İş Parçacıkları'nın seçili olduğundan emin olun.

Paralel Yığınlar penceresini kullanarak birden çok çağrı yığınını aynı anda tek bir görünümde görüntüleyebilirsiniz. Aşağıdaki çizimde Çağrı Yığını penceresinin üzerindeki Paralel Yığınlar penceresi gösterilmektedir.

Screenshot of Threads view in Parallel Stacks window.

Threads view in Parallel Stacks window

Main iş parçacığının çağrı yığını bir kutuda görünür ve diğer dört iş parçacığının çağrı yığınları başka bir kutuda gruplandırılır. Yığın çerçeveleri aynı yöntem bağlamlarını paylaştığından dört iş parçacığı birlikte gruplandırılır; yani, aynı yöntemlerdedir: A, Bve C. Aynı kutuyu paylaşan iş parçacığı kimliklerini ve iş parçacıklarının adlarını görüntülemek için üst bilgi ([#] İş Parçacıkları) içeren kutunun üzerine gelin. Geçerli iş parçacığı kalın olarak görüntülenir.

Screenshot of Tooltip that shows thread IDs and names.

Tooltip that shows thread IDs and names

Sarı ok, geçerli iş parçacığının etkin yığın çerçevesini gösterir.

Çağrı Yığını penceresinde sağ tıklayarak yığın çerçeveleri (Modül Adları, Parametre Türleri, Parametre Adları, Parametre Değerleri, Satır Numaraları ve Bayt Uzaklıkları) için ne kadar ayrıntı göstereceğini ayarlayabilirsiniz.

Kutunun etrafındaki mavi vurgu, geçerli iş parçacığının bu kutunun bir parçası olduğunu gösterir. Geçerli iş parçacığı, araç ipucundaki kalın yığın çerçevesiyle de gösterilir. İş Parçacıkları penceresinde Ana iş parçacığına çift tıklarsanız, Paralel Yığınlar penceresindeki vurgu okunun buna göre hareket ettiğini görebilirsiniz.

Screenshot of Highlighted main thread in Parallel Stacks window.

Highlighted main thread in Parallel Stacks window

İkinci kesme noktasına kadar yürütmeyi sürdür

İkinci kesme noktasına isabet edene kadar yürütmeye devam etmek için Hata Ayıkla menüsünde Devam'ı seçin. Aşağıdaki çizimde, ikinci kesme noktasındaki iş parçacığı ağacı gösterilmektedir.

Screenshot of Parallel Stacks window that shows many branches.

Parallel Stacks window that shows many branches

İlk kesme noktasında, dört iş parçacığının tümü S.A'dan S.B'ye ve S.C yöntemlerine geçti. Bu bilgiler Paralel Yığınlar penceresinde görünmeye devam eder , ancak dört iş parçacığı daha da ilerlemiş olur. Biri S.D.'ye ve sonra da S.E.'ye devam etti. Bir diğeri de S.F, S.G ve S.H. ile devam etti. Diğer iki kişi S.I ve S.J'ye devam etti ve oradan biri S.K'ye, diğeri de kullanıcı olmayan Dış Kod'a gitti.

İş parçacığı kimliklerini ve diğer çerçeve ayrıntılarını görmek için yığın çerçevelerinin üzerine gelebilirsiniz. Mavi vurgu geçerli iş parçacığını, sarı ok ise geçerli iş parçacığının etkin yığın çerçevesini gösterir.

İş parçacıklarının iş parçacığı kimliklerini görmek için kutu üst bilgisinin (örneğin, 1 İş Parçacığı veya 2 İş Parçacığı) üzerine gelebilirsiniz. İş parçacığı kimliklerini ve diğer çerçeve ayrıntılarını görmek için yığın çerçevelerinin üzerine gelebilirsiniz. Mavi vurgu geçerli iş parçacığını, sarı ok ise geçerli iş parçacığının etkin yığın çerçevesini gösterir.

Bez iş parçacıkları simgesi (ara sıralı çizgiler), özyinelemeli olmayan iş parçacıklarının etkin yığın çerçevelerini gösterir. Çağrı Yığını penceresinde S.B'ye çift tıklayarak çerçeveleri değiştirin. Paralel Yığınlar penceresi, eğri ok simgesi kullanarak geçerli iş parçacığının geçerli yığın çerçevesini gösterir.

Dekont

Paralel Yığınlar penceresindeki tüm simgelerin açıklaması için bkz . Paralel Yığınlar penceresini kullanma.

İş Parçacıkları penceresinde iş parçacıkları arasında geçiş yapın ve Paralel Yığınlar penceresindeki görünümün güncelleştirildiğini gözlemleyin.

Paralel Yığınlar penceresindeki kısayol menüsünü kullanarak başka bir iş parçacığına veya başka bir iş parçacığının başka bir çerçevesine geçiş yapabilirsiniz. Örneğin, S.J'ye sağ tıklayın, Çerçeveye Geç'in üzerine gelin ve bir komut seçin.

Screenshot of Parallel Stacks Path of Execution.

Parallel Stacks Path of Execution

S.C'ye sağ tıklayın ve Çerçeveye Geç'in üzerine gelin. Komutlardan birinin geçerli iş parçacığının yığın çerçevesini gösteren bir onay işareti vardır. Aynı iş parçacığının bu çerçevesine geçebilirsiniz (yalnızca eğri ok hareket eder) veya diğer iş parçacığına geçebilirsiniz (mavi vurgu da hareket eder). Aşağıdaki çizimde alt menü gösterilmektedir.

Screenshot of Stacks menu with 2 options on C while J is current.

Stacks menu with 2 options on C while J is current

Bir yöntem bağlamı yalnızca bir yığın çerçevesiyle ilişkilendirildiğinde, kutu üst bilgisi 1 İş Parçacığı görüntüler ve çift tıklayarak buna geçiş yapabilirsiniz. Kendisiyle ilişkilendirilmiş 1'den fazla çerçeve içeren bir yöntem bağlamını çift tıklatırsanız, menü otomatik olarak açılır. Yöntem bağlamlarının üzerine geldiğinizde, sağdaki siyah üçgene dikkat edin. Bu üçgene tıklanırken kısayol menüsü de görüntülenir.

Çok sayıda iş parçacığı olan büyük uygulamalar için iş parçacıklarının yalnızca bir alt kümesine odaklanmak isteyebilirsiniz. Paralel Yığınlar penceresi yalnızca bayrak eklenmiş iş parçacıkları için çağrı yığınlarını görüntüleyebilir. İş parçacıklarına bayrak eklemek için, kısayol menüsünü veya bir iş parçacığının ilk hücresini kullanın.

Araç çubuğunda, liste kutusunun yanındaki Yalnızca Bayrak eklenmişi Göster düğmesini seçin.

Screenshot of Parallel Stacks window and tooltip.

Parallel Stacks window and tooltip

Artık Paralel Yığınlar penceresinde yalnızca bayrak eklenmiş iş parçacıkları gösterilir.

Yürütmeyi üçüncü kesme noktasına kadar sürdür

  1. Üçüncü kesme noktasına isabet edene kadar yürütmeye devam etmek için Hata Ayıkla menüsünde Devam'ı seçin.

    Aynı yöntemde birden çok iş parçacığı olduğunda ancak yöntem çağrı yığınının başında olmadığında, yöntem farklı kutularda görünür. Geçerli kesme noktasına örnek olarak, içinde üç iş parçacığı bulunan ve üç kutuda görünen S.L örnektir. S.L.'ye çift tıklayın.

    Screenshot of Execution path in Parallel Stacks window.

    Execution path in Parallel Stacks window

    Diğer iki kutuda S.L'nin kalın olduğuna dikkat edin, böylece başka nerede göründüğünü görebilirsiniz. S.L'ye çağrı yapan çerçeveleri ve çağırdığı çerçeveleri görmek istiyorsanız, araç çubuğundaki Yöntem Görünümünü Değiştir düğmesini seçin. Aşağıdaki çizimde Paralel Yığınlar penceresinin yöntem görünümü gösterilmektedir .

    Screenshot of Method view in Parallel Stacks window.

    Method view in Parallel Stacks window

    Diyagramın seçili yöntemde nasıl özetlendiğine ve görünümün ortasında kendi kutusuna yerleştirildiğine dikkat edin. Arayanlar ve arayanlar sırasıyla üstte ve altta görünür. Bu moddan çıkmak için Yöntem Görünümünü Değiştir düğmesini yeniden seçin.

    Paralel Yığınlar penceresinin kısayol menüsünde aşağıdaki diğer öğeler de bulunur.

    • Onaltılık Ekran , araç ipuçlarındaki sayıları ondalık ve onaltılık arasında değiştirir.

    • Simge Ayarlar ilgili iletişim kutularını açın.

    • Kaynakta İş Parçacıklarını Göster, kaynak kodunuzda iş parçacıklarının konumunu gösteren iş parçacığı işaretçilerinin görüntülenmesini değiştirir.

    • Dış Kodu Göster, kullanıcı kodunda olmasalar bile tüm çerçeveleri görüntüler. Diyagramın diğer çerçevelere uyacak şekilde genişletilebileceğini görmek için deneyin (bunlar için simgeleriniz olmadığından soluk olabilir).

  2. Paralel Yığınlar penceresinde, araç çubuğundaki Geçerli Yığın Çerçevesine Otomatik Kaydır düğmesinin açık olduğundan emin olun.

    Büyük diyagramlarınız olduğunda ve bir sonraki kesme noktasına geçtiğinde, görünümün geçerli iş parçacığının etkin yığın çerçevesine otomatik olarak kaydırılmasını isteyebilirsiniz; yani, önce kesme noktasına isabet eden iş parçacığıdır.

  3. Devam etmeden önce Paralel Yığınlar penceresinde sola ve aşağı doğru kaydırın.

Dördüncü kesme noktasına kadar yürütmeyi sürdür

  1. Dördüncü kesme noktasına isabet edene kadar yürütmeye devam etmek için Hata Ayıkla menüsünde Devam'ı seçin.

    Görünümün otomatik olarak yerine nasıl yerlendiğine dikkat edin. İş Parçacıkları penceresinde iş parçacıklarını değiştirin veya Çağrı Yığını penceresindeki yığın çerçevelerini değiştirin ve görünümün her zaman doğru çerçeveye otomatik olarak kaydına dikkat edin. Geçerli Araç Çerçevesine Otomatik Kaydırma seçeneğini kapatın ve farkı görüntüleyin.

    Kuş Bakışı Görünümü , Paralel Yığınlar penceresindeki büyük diyagramlara da yardımcı olur. Varsayılan olarak Kuş Bakışı Görünümü açıktır. Ancak, aşağıdaki çizimde gösterildiği gibi pencerenin sağ alt köşesindeki kaydırma çubukları arasındaki düğmeye tıklayarak bu düğmeyi değiştirebilirsiniz.

    Screenshot of Birds eye view in Parallel Stacks window.

    Bird's-eye view in Parallel Stacks window

    Kuş bakışı görünümünde, diyagramın çevresinde hızla kaydırmak için dikdörtgeni taşıyabilirsiniz.

    Diyagramı herhangi bir yönde taşımanın bir diğer yolu da diyagramın boş bir alanını seçmek ve istediğiniz yere sürüklemektir.

    Diyagramı yakınlaştırmak ve uzaklaştırmak için fare tekerleğini hareket ettirirken CTRL tuşunu basılı tutun. Alternatif olarak, araç çubuğundaki Yakınlaştır düğmesini seçin ve ardından Yakınlaştırma aracını kullanın.

    Ayrıca, Araçlar menüsüne, Seçenekler'e tıklayarak ve ardından Hata Ayıklama düğümü altındaki seçeneği belirleyerek veya temizleyerek yığınları alttan yukarı değil, yukarıdan aşağı yönde görüntüleyebilirsiniz.

  2. Devam etmeden önce, Yürütmeyi sonlandırmak için Hata Ayıkla menüsünde Hata Ayıklamayı Durdur'u seçin.

Paralel Görevler Penceresini ve Paralel Yığınlar penceresinin Görevler Görünümünü kullanma

Devam etmeden önce önceki yordamları tamamlamanızı öneririz.

İlk kesme noktasına isabet edene kadar uygulamayı yeniden başlatın:

  1. Hata Ayıklamenüsünde Hata Ayıklamayı Başlat'ı seçin ve ilk kesme noktasına ulaşmayı bekleyin.

  2. Hata Ayıkla menüsünde Windows'un üzerine gelin ve İş Parçacıkları'nı seçin. İş Parçacıkları penceresini Visual Studio'nun en altına sabitleyin.

  3. Hata Ayıkla menüsünde Windows'un üzerine gelin ve Çağrı Yığını'nı seçin. Çağrı Yığını penceresini Visual Studio'nun en altına sabitleyin.

  4. İş Parçacıkları penceresinde bir iş parçacığını geçerli hale getirmek için çift tıklayın. Geçerli iş parçacıkları sarı oka sahiptir. Geçerli iş parçacığını değiştirdiğinizde, diğer pencereler güncelleştirilir. Ardından görevleri inceleyeceğiz.

  5. Hata Ayıkla menüsünde Windows'un üzerine gelin ve Görevler'i seçin. Aşağıdaki çizimde Görevler penceresi gösterilmektedir.

    Screenshot of Four running tasks in Tasks window.

    Four running tasks in Tasks window

    Çalışan her Görev için, aynı adlı özellik tarafından döndürülen kimliğini, onu çalıştıran iş parçacığının kimliğini ve adını, konumunu (bunun üzerine gelindiğinde çağrı yığınının tamamını içeren bir araç ipucu görüntülenir) okuyabilirsiniz. Ayrıca, Görev sütununun altında göreve geçirilen yöntemi, başka bir deyişle başlangıç noktasını görebilirsiniz.

    Herhangi bir sütunu sıralayabilirsiniz. Sıralama sütununu ve yönünü gösteren sıralama karakterine dikkat edin. Sütunları sola veya sağa sürükleyerek de yeniden sıralayabilirsiniz.

    Sarı ok geçerli görevi gösterir. Bir göreve çift tıklayarak veya kısayol menüsünü kullanarak görevler arasında geçiş yapabilirsiniz. Görevleri değiştirdiğinizde, temel alınan iş parçacığı güncel hale gelir ve diğer pencereler güncelleştirilir.

    Bir görevden diğerine el ile geçiş yaptığınızda, ok ana hattı, geçerli hata ayıklayıcısı bağlamını özyinelemeli olmayan bir görevin bağlamını gösterir.

    Bir görevden diğerine el ile geçiş yaptığınızda sarı ok hareket eder, ancak hata ayıklayıcının bozulmasına neden olan görevi yine de beyaz bir ok gösterir.

İkinci kesme noktasına kadar yürütmeyi sürdür

İkinci kesme noktasına isabet edene kadar yürütmeye devam etmek için Hata Ayıkla menüsünde Devam'ı seçin.

Daha önce Durum sütununda tüm görevler Etkin olarak gösteriliyordu, ancak şimdi iki görev Engellendi olarak gösteriliyordu. Görevler birçok farklı nedenden dolayı engellenebilir. Durum sütununda, bekleme görevinin üzerine gelerek neden engellendiğini öğrenin. Örneğin, aşağıdaki çizimde 11. görev 12. görevi bekliyor.

Screenshot of Two waiting tasks in Tasks window.

Daha önce Durum sütununda tüm görevler Etkin olarak gösteriliyordu, ancak şimdi iki görev Engellendi olarak gösteriliyordu. Görevler birçok farklı nedenden dolayı engellenebilir. Durum sütununda, bekleme görevinin üzerine gelerek neden engellendiğini öğrenin. Örneğin, aşağıdaki çizimde 4. görev 5. görevi bekliyor.

Two waiting tasks in Tasks window

4. Görev ise 2. göreve atanan iş parçacığına ait bir izleyiciyi bekliyor. (Üst bilgi satırına sağ tıklayın ve 2. görevin iş parçacığı atama değerini görüntülemek için İş Parçacığı Atamasını Sütunlar>).

Waiting task and tooltip in Tasks window

Görevler penceresinin ilk sütunundaki bayrağı tıklatarak bir göreve bayrak ekleyebilirsiniz.

Aynı hata ayıklama oturumundaki farklı kesme noktaları arasındaki görevleri izlemek veya çağrı yığınları Paralel Yığınlar penceresinde gösterilen görevleri filtrelemek için bayraklama kullanabilirsiniz.

Daha önce Paralel Yığınlar penceresini kullandığınızda, uygulama iş parçacıklarını görüntülemişsinizdir. Paralel Yığınlar penceresini yeniden görüntüleyin, ancak bu kez uygulama görevlerini görüntüleyin. Sol üstteki kutuda Görevler'i seçerek bunu yapın. Aşağıdaki çizimde Görevler Görünümü gösterilmektedir.

Screenshot of Tasks view in Parallel Stacks window.

Tasks view in Parallel Stacks window

Şu anda görevleri yürütmemiş iş parçacıkları, Paralel Yığınlar penceresinin Görevler Görünümünde gösterilmez. Ayrıca, görevleri yürüten iş parçacıkları için, görevlerle ilgili olmayan bazı yığın çerçeveleri yığının üstünden ve altından filtrelenir.

Görevler penceresini yeniden görüntüleyin. Sütunun kısayol menüsünü görmek için herhangi bir sütun üst bilgisine sağ tıklayın.

Sütun eklemek veya kaldırmak için kısayol menüsünü kullanabilirsiniz. Örneğin, AppDomain sütunu seçilmez; bu nedenle listede görüntülenmez. Üst Öğe'yi seçin. Üst sütun, dört görevden herhangi biri için değer olmadan görünür.

Yürütmeyi üçüncü kesme noktasına kadar sürdür

Üçüncü kesme noktasına isabet edene kadar yürütmeye devam etmek için Hata Ayıkla menüsünde Devam'ı seçin.

Screenshot of Parent-child view in Tasks window.

Bu örnek çalıştırmada, görev 11 ve görev 12'nin aynı iş parçacığında çalıştığına dikkat edin (gizliyse İş Parçacığı Ataması sütununu gösterin). Bu bilgiler İş Parçacıkları penceresinde görüntülenmez; görevler penceresinin başka bir avantajını burada görebilirsiniz. Bunu onaylamak için Paralel Yığınlar penceresini görüntüleyin. Görevleri görüntülediğinizden emin olun. Paralel Yığınlar penceresinde araç ipuçlarını tarayarak 11. ve 12. görevleri bulabilirsiniz.

Task view in Parallel Stacks window

5. görev olan yeni bir görev çalışıyor ve 4. görev bekliyor. Durum penceresinde bekleme görevinin üzerine gelerek nedenini görebilirsiniz. Üst sütunda, 4. görevin 5. görevin üst öğesi olduğuna dikkat edin.

Üst-alt ilişkiyi daha iyi görselleştirmek için sütun üst bilgi satırına sağ tıklayın ve Üst Alt Görünüm'ü seçin. Aşağıdaki çizimi görmeniz gerekir.

Parent-child view in Tasks window

Görev 4 ve görev 5'in aynı iş parçacığında çalıştığına dikkat edin (gizliyse İş Parçacığı Ataması sütununu gösterin). Bu bilgiler İş Parçacıkları penceresinde görüntülenmez; görevler penceresinin başka bir avantajını burada görebilirsiniz. Bunu onaylamak için Paralel Yığınlar penceresini görüntüleyin. Görevleri görüntülediğinizden emin olun. Görevler penceresinde çift tıklayarak 4. ve 5. görevleri bulun. Bunu yaptığınızda, Paralel Yığınlar penceresindeki mavi vurgu güncelleştirilir. Paralel Yığınlar penceresinde araç ipuçlarını tarayarak 4. ve 5. görevleri de bulabilirsiniz.

Task view in Parallel Stacks window

Paralel Yığınlar penceresinde S.P'ye sağ tıklayın ve ardından İş Parçacığına Git'i seçin. Pencere İş Parçacıkları Görünümü'ne geçer ve karşılık gelen çerçeve görünümdedir. Her iki görevi de aynı iş parçacığında görebilirsiniz.

Highlighted thread in threads view

Bu, Paralel Yığınlar penceresindeki Görevler Görünümünün İş Parçacıkları penceresiyle karşılaştırıldığında başka bir avantajıdır.

Dördüncü kesme noktasına kadar yürütmeyi sürdür

Üçüncü kesme noktasına isabet edene kadar yürütmeye devam etmek için Hata Ayıkla menüsünde Devam'ı seçin. Kimlik sütunu üst bilgisini seçerek kimliklere göre sıralayın. Aşağıdaki çizimi görmeniz gerekir.

Screenshot of Four task states in Parallel Stacks window.

Görev 10 ve görev 11 artık birbirini bekliyor ve engelleniyor. Şimdi zamanlanmış birkaç yeni görev de vardır. Zamanlanmış görevler, kodda başlatılmış ancak henüz çalıştırılmayan görevlerdir. Bu nedenle, Konum ve İş Parçacığı Ataması sütunları varsayılan iletileri gösterir veya boş olur.

Four task states in Parallel Stacks window

5. görev tamamlandığından, artık görüntülenmez. Bilgisayarınızda bu durum geçerli değilse ve kilitlenme gösterilmiyorsa F11 tuşuna basarak bir kez adım atabilirsiniz.

Görev 3 ve görev 4 artık birbirini bekliyor ve engelleniyor. Ayrıca 2. görevin alt öğeleri olan ve şimdi zamanlanmış 5 yeni görev vardır. Zamanlanmış görevler, kodda başlatılmış ancak henüz çalıştırılmayan görevlerdir. Bu nedenle, Konum ve İş Parçacığı Atama sütunları boş olur.

Paralel Yığınlar penceresini yeniden görüntüleyin. Her kutunun üst bilgisinde, iş parçacığı kimliklerini ve adlarını gösteren bir araç ipucu vardır. Paralel Yığınlar penceresinde Görevler Görünümü'ne geçin. Aşağıdaki çizimde gösterildiği gibi, görev kimliğini ve adını ve görevin durumunu görmek için üst bilginin üzerine gelin.

Header tooltip in Parallel Stacks window

Görevleri sütuna göre gruplandırabilirsiniz. Görevler penceresinde Durum sütunu üst bilgisine sağ tıklayın ve Ardından Duruma Göre Gruplandır'ı seçin. Aşağıdaki çizimde, durumlara göre gruplandırılmış Görevler penceresi gösterilmektedir.

Screenshot of Grouped tasks in Tasks window.

Grouped tasks in Tasks window

Başka bir sütuna göre de gruplandırabilirsiniz. Görevleri gruplandırarak, görevlerin bir alt kümesine odaklanabilirsiniz. Daraltılabilir her grup, birlikte gruplandırılmış öğelerin bir sayısına sahiptir.

İncelenmesi gereken Görevler penceresinin son özelliği, bir göreve sağ tıkladığınızda görüntülenen kısayol menüsüdür.

Kısayol menüsünde görevin durumuna bağlı olarak farklı komutlar görüntülenir. Komutlar Kopyala, Tümünü Seç, Onaltılık Görüntü, Göreve Geç, Atanan İş Parçacığını Dondur, Tüm İş Parçacıklarını Dondur ama Bu ve Atanan İş Parçacığını Çöz ve Bayrak içerebilir.

Bir görevin veya görevlerin temel iş parçacığını veya atanan iş parçacığı dışında tüm iş parçacıklarını dondurabilirsiniz. Donmuş bir iş parçacığı, Görevler penceresinde, İş Parçacıkları penceresinde olduğu gibi mavi bir duraklatma simgesiyle gösterilir.

Özet

Bu kılavuzda Paralel Görevler ve Paralel Yığınlar hata ayıklayıcı pencereleri gösterilmiştir. Bu pencereleri, çok iş parçacıklı kod kullanan gerçek projelerde kullanın. C++, C# veya Visual Basic ile yazılmış paralel kodu inceleyebilirsiniz.