Dziś kolejna wskazówka dotycząca debugowania. W poprzednim poście pokazałem Parralel Stacks, umożliwiający wizualizację wątków. Jest to niezastąpione, jeśli nie wiemy w którym miejscu lub który wątek powoduje problem. Dzisiaj kolejna opcja, “Show Threads in Source”. Najpierw stwórzmy jakieś wątki np.:
internal class Program { private static readonly object Sync = new object(); private static void Main(string[] args) { for (int i = 0; i < 50; i++) { Task.Factory.StartNew(() => { lock (Sync) { Thread.Sleep(5000000); } }); } Console.ReadLine(); } }
Opcja Show Threads in Source pokaże nam, jakie inne wątki są wykonywane w danym obszarze kodu. Dlaczego jest to takie ważne? Chodzi oczywiście o deadlock’i czy zmienianie w tym samie czasie tej samej zmiennej. Po uruchomieniu powyższej aplikacji, po kilku sekundach klikamy break-in, aby uruchomić debugger. Następnie otwieramy okno Threads:
Kliknijmy na wątku, któremu udało się wejść do sekcji krytycznej:
Na tym etapie nic specjalnego nie dzieje się. Wiemy tylko, że jeden wątek będzie blokował pozostałe, ponieważ zdefiniowaliśmy sekcję krytyczną. Czasami sprawa nie wygląda tak prosto i nie wiemy, jakie inne wątki aktualnie wykonują dany kod – zwykle mamy scheduler’y i bardziej skomplikowaną infrastrukturę.
Opcję Show Threads in Source możemy wybrać z Toolbar’a albo z menu:
Pojawią się dodatkowe ikonki, po lewej stronie kodu źródłowego:
Pokazują one, że jakieś wątki wykonują ten kod. W powyższym przypadku mamy dwie ikony. Jedna jest na lock, co się zgadza ponieważ 49 wątków czeka na wejście do sekcji krytycznej oraz jeden wątek jest na Console.ReadLine – co również ma sens ponieważ Main Thread właśnie będzie czekał na input od użytkownika.
Najeżdżając kursorem na ikonkę, dostaniemy interaktywną listę wykonywanych tam wątków:
Bardzo przydatna funkcja, szczególnie w przypadku analizowania blokad.