Bagikan melalui


Mulai men-debug aplikasi multithread (C#, Visual Basic, C++)

Visual Studio menyediakan beberapa alat dan elemen antarmuka pengguna untuk membantu Anda men-debug aplikasi multithreaded. Tutorial ini menunjukkan cara menggunakan penanda utas, jendela Tumpukan Paralel , jendela Parallel Watch , titik henti kondisi, dan titik henti filter. Menyelesaikan tutorial ini membiasakan Anda dengan fitur Visual Studio untuk men-debug aplikasi multithreaded.

Kedua artikel ini memberikan informasi tambahan tentang menggunakan alat debugging multithreaded lainnya:

Langkah pertama adalah membuat proyek aplikasi multithreaded.

Membuat proyek aplikasi multithread

  1. Buka Visual Studio dan buat proyek baru.

    Jika jendela Mulai tidak terbuka, pilih File>Jendela Mulai.

    Pada jendela mulai, pilih Buat proyek baru.

    Pada jendela Buat proyek baru , masukkan atau ketik konsol di kotak pencarian. Selanjutnya, pilih C#, C++, atau Visual Basic dari daftar Bahasa, lalu pilih Windows dari daftar Platform.

    Setelah Anda menerapkan filter bahasa dan platform, pilih templat Aplikasi Konsol untuk .NET atau C++, lalu pilih Berikutnya.

    Nota

    Jika Anda tidak melihat templat yang benar, buka Alat>Dapatkan Alat dan Fitur..., yang membuka Alat Penginstal Visual Studio. Pilih pengembangan desktop .NET atau Pengembangan desktop dengan beban kerja C++ , lalu pilih Ubah.

    Di jendela Konfigurasikan proyek baru Anda , ketik atau masukkan MyThreadWalkthroughApp di kotak Nama proyek . Kemudian, pilih Berikutnya atau Buat, opsi mana pun yang tersedia.

    Untuk proyek .NET Core atau .NET 5+, pilih kerangka kerja target yang direkomendasikan atau .NET 8, lalu pilih Buat.

    Proyek konsol baru muncul. Setelah proyek dibuat, file sumber muncul. Bergantung pada bahasa yang Anda pilih, file sumber mungkin disebut Program.cs, MyThreadWalkthroughApp.cpp, atau Module1.vb.

  2. Hapus kode yang muncul di file sumber dan ganti dengan kode yang diperbarui berikut. Pilih cuplikan yang sesuai untuk konfigurasi kode Anda.

    using System;
    using System.Threading;
    
    public class ServerClass
    {
    
        static int count = 0;
        // The method that will be called when the thread is started.
        public void InstanceMethod()
        {
            Console.WriteLine(
                "ServerClass.InstanceMethod is running on another thread.");
    
            int data = count++;
            // Pause for a moment to provide a delay to make
            // threads more apparent.
            Thread.Sleep(3000);
            Console.WriteLine(
                "The instance method called by the worker thread has ended. " + data);
        }
    }
    
    public class Simple
    {
        public static void Main()
        {
            for (int i = 0; i < 10; i++)
            {
                CreateThreads();
            }
        }
        public static void CreateThreads()
        {
            ServerClass serverObject = new ServerClass();
    
            Thread InstanceCaller = new Thread(new ThreadStart(serverObject.InstanceMethod));
            // Start the thread.
            InstanceCaller.Start();
    
            Console.WriteLine("The Main() thread calls this after "
                + "starting the new InstanceCaller thread.");
    
        }
    }
    
  3. Pada menu File, pilih Simpan Semua.

  4. (Hanya Visual Basic) Di Penjelajah Solusi (panel kanan), klik kanan simpul proyek, pilih Properti. Di bawah tab Aplikasi , ubah objek Startup menjadi Sederhana.

Memperbaiki aplikasi multithread

  1. Di editor kode sumber, cari cuplikan kode berikut:

    Thread.Sleep(3000);
    Console.WriteLine();
    
  2. Klik kiri di gutter kiri dari Thread.Sleep atau, untuk C++, pernyataan std::this_thread::sleep_for untuk menyisipkan titik henti baru.

    Di margin, lingkaran merah menunjukkan bahwa titik henti ditetapkan di lokasi ini.

  3. Pada menu Debug , pilih Mulai Debugging (F5).

    Visual Studio membangun solusi, aplikasi mulai berjalan dengan debugger terpasang, lalu aplikasi berhenti di titik henti.

  4. Di editor kode sumber, temukan baris yang berisi titik henti.

Temukan penanda utas

  1. Di Toolbar Debug, pilih tombol Tampilkan Utas di SumberTampilkan Utas di Sumber.

  2. Tekan F11 dua kali untuk memajukan debugger.

  3. Lihat selokan di sisi kiri jendela. Pada baris ini, perhatikan ikon penanda utasThread Marker yang mirip dengan dua utas yang terjalin. Penanda utas menunjukkan bahwa utas dihentikan di lokasi ini.

    Penanda utas dapat disembunyikan sebagian oleh titik henti.

  4. Arahkan penunjuk ke atas penunjuk benang. DataTip muncul memberi tahu Anda nama dan nomor ID utas untuk setiap utas yang dihentikan. Dalam hal ini, namanya mungkin <noname>.

    Cuplikan layar ID Utas dalam DataTip.

  5. Pilih penanda utas untuk melihat opsi yang tersedia di menu pintasan.

Lihat lokasi utas

Di jendela Tumpukan Paralel, Anda dapat beralih antara tampilan Utas dan tampilan Tugas (untuk pemrograman berbasis tugas), dan Anda dapat melihat informasi panggilan tumpukan untuk setiap utas. Dalam aplikasi ini, kita dapat menggunakan tampilan Threads.

  1. Buka jendela Tumpukan Paralel dengan memilih Debug>Tumpukan Paralel>. Anda akan melihat sesuatu yang mirip dengan yang berikut ini. Informasi yang tepat dapat berbeda tergantung pada lokasi saat ini dari setiap utas, perangkat keras Anda, dan bahasa pemrograman Anda.

    Cuplikan layar Jendela Tumpukan Paralel.

    Dalam contoh ini, dari kiri ke kanan kita melihat informasi ini untuk kode terkelola:

    • Alur saat ini (panah kuning) telah memasuki ServerClass.InstanceMethod. Anda dapat melihat ID utas dan bingkai tumpukan utas dengan mengarahkan mouse ke atas ServerClass.InstanceMethod.
    • Thread 31724 sedang menunggu kunci milik Thread 20272.
    • Utas Utama (sisi kiri) telah berhenti pada [Kode Eksternal], yang dapat Anda lihat secara rinci jika Anda memilih Tampilkan Kode Eksternal.

    Jendela Tumpukan Paralel

    Dalam contoh ini, dari kiri ke kanan kita melihat informasi ini untuk kode terkelola:

    • Utas Utama (sisi kiri) telah berhenti pada Thread.Start, di mana titik berhenti diidentifikasi oleh ikon penanda utas Thread Marker.
    • Dua utas telah memasuki ServerClass.InstanceMethod, salah satunya adalah utas saat ini (panah kuning), sementara utas lainnya telah berhenti di Thread.Sleep.
    • Utas baru (di sebelah kanan) juga dimulai tetapi dihentikan pada ThreadHelper.ThreadStart.
  2. Untuk melihat utas dalam tampilan daftar, pilih Debug>Windows>Utas.

    Cuplikan layar Jendela Utas.

    Dalam tampilan ini, Anda dapat dengan mudah melihat bahwa utas 20272 adalah utas Utama dan saat ini terletak di kode eksternal, khususnya System.Console.dll.

    Nota

    Untuk informasi selengkapnya tentang menggunakan jendela Utas , lihat Panduan: Men-debug Aplikasi Multithreaded.

  3. Klik kanan entri di jendela Parallel Stacks atau Threads untuk melihat opsi yang tersedia pada menu pintasan.

    Anda dapat mengambil berbagai tindakan dari menu klik kanan ini. Untuk tutorial ini, Anda menjelajahi lebih banyak detail ini di jendela Parallel Watch (bagian berikutnya).

Memantau perubahan pada variabel

  1. Buka jendela Parallel Watch dengan memilih Debug>Windows>Parallel Watch>Parallel Watch 1.

  2. Pilih sel tempat Anda melihat <Add Watch> teks (atau sel header kosong di kolom keempat) dan masukkan data.

    Nilai untuk variabel data untuk setiap utas muncul di jendela.

  3. Pilih sel tempat Anda melihat <Add Watch> teks (atau sel header kosong di kolom kelima) dan masukkan count.

    Nilai variabel count untuk setiap utas muncul di jendela. Jika Anda belum melihat informasi ini secara lengkap, coba tekan F11 beberapa kali untuk memajukan eksekusi utas di debugger.

    Jendela Jam Tangan Paralel

  4. Klik kanan pada salah satu baris di jendela untuk melihat opsi yang tersedia.

Tandai dan hapus tanda pada utas

Anda dapat menandai utas untuk memantau utas yang penting dan mengabaikan utas lainnya.

  1. Di jendela Parallel Watch , tahan tombol Shift dan pilih beberapa baris.

  2. Klik kanan dan pilih Bendera.

    Semua utas yang dipilih ditandai. Sekarang, Anda dapat memfilter untuk hanya menampilkan utas yang ditandai.

  3. Di jendela Pengawasan Paralel, pilih tombol Tampilkan Hanya Utas yang DitandaiTampilkan Utas yang Ditandai.

    Hanya utas yang ditandai yang muncul dalam daftar.

    Petunjuk / Saran

    Setelah menandai beberapa utas, Anda dapat mengklik kanan baris kode di editor kode dan memilih Jalankan Utas yang Ditandai ke Kursor. Pastikan untuk memilih kode yang dapat dijangkau oleh semua utas yang ditandai. Visual Studio akan menjeda utas pada baris kode yang dipilih, sehingga lebih mudah untuk mengontrol urutan eksekusi dengan membekukan dan mencairkan utas.

  4. Pilih tombol Perlihatkan Hanya Utas yang Ditandai lagi untuk beralih kembali ke mode Tampilkan Semua Utas .

  5. Untuk menghapus tanda pada utas, klik-kanan satu atau beberapa utas yang ditandai di jendela Parallel Watch dan pilih Hapus Tanda.

Membekukan dan mencairkan eksekusi utas

Petunjuk / Saran

Anda dapat membekukan dan mencairkan (menangguhkan dan melanjutkan) utas untuk mengontrol urutan di mana utas melakukan pekerjaan. Ini dapat membantu Anda mengatasi masalah konkurensi seperti kebuntuan dan kondisi balapan.

  1. Di jendela Parallel Watch , dengan semua baris dipilih, klik kanan dan pilih Bekukan.

    Di kolom kedua, ikon jeda muncul untuk setiap baris. Ikon jeda menunjukkan bahwa utas dibekukan.

  2. Batal pilih semua baris lainnya dengan memilih satu baris saja.

  3. Klik kanan baris dan pilih Cairkan.

    Ikon jeda menghilang dari baris ini, yang menunjukkan utas tidak lagi dibekukan.

  4. Beralih ke editor kode dan tekan F11. Hanya utas yang tidak beku yang berjalan.

    Aplikasi ini mungkin juga memulai beberapa utas baru. Utas baru tidak ditandai dan tidak dibekukan.

Ikuti satu utas dengan titik henti kondisional

Sangat membantu untuk mengikuti eksekusi satu utas di debugger. Salah satu cara untuk melakukannya adalah dengan membekukan utas yang tidak Anda minati. Dalam beberapa skenario, Anda mungkin perlu mengikuti satu utas tanpa membekukan utas lain, misalnya untuk mereproduksi bug tertentu. Untuk mengikuti suatu utas tanpa membekukan utas lain, Anda harus menghindari masuk ke dalam kode kecuali pada utas yang Anda minati. Anda dapat melakukan tugas ini dengan mengatur titik henti bersyarat.

Anda dapat mengatur titik jeda berdasarkan kondisi berbeda, seperti nama utas atau ID utas. Sangat berguna untuk mengatur kondisi pada data yang Anda ketahui unik untuk setiap utas. Pendekatan ini umum selama debugging ketika Anda lebih tertarik pada nilai data tertentu daripada pada utas tertentu.

  1. Klik kanan titik henti yang sebelumnya Anda buat dan pilih Kondisi.

  2. Di jendela Pengaturan Titik Henti, masukkan data == 5 untuk ekspresi bersyarat.

    Penanda Kondisional

    Petunjuk / Saran

    Jika Anda lebih tertarik dengan utas tertentu, gunakan nama utas atau ID utas untuk kondisi tersebut. Untuk melakukan ini di jendela Pengaturan Titik Henti, pilih Filter alih-alih ekspresi Kondisional, dan ikuti petunjuk filter. Anda mungkin ingin menamai thread dalam kode aplikasi Anda, karena ID thread berubah ketika Anda memulai ulang debugger.

  3. Tutup jendela Pengaturan Titik Henti .

  4. Pilih tombol Mulai Ulang Aplikasi untuk memulai ulang sesi debugging Anda.

    Anda memecah kode pada utas tempat nilai variabel data adalah 5. Di jendela Parallel Watch , cari panah kuning yang menunjukkan konteks debugger saat ini.

  5. Sekarang, Anda dapat melangkahi kode (F10) dan melangkah ke kode (F11) dan mengikuti eksekusi utas tunggal.

    Selama kondisi titik henti unik untuk utas, dan debugger tidak menemukan titik henti lain di utas lain (Anda mungkin perlu menonaktifkannya), Anda dapat melangkahi dan menelusuri kode tanpa beralih ke utas lain.

    Nota

    Ketika Anda memajukan debugger, semua utas akan berjalan. Namun, debugger tidak akan memecah kode pada utas lain kecuali salah satu utas lainnya mencapai titik henti.