Most developers use about 20% of Visual Studio's debugger — F9 to set a breakpoint, F5 to run, F10/F11 to step. The other 80% is where the real productivity lives. Here are seven techniques worth adopting this week.

1. Conditional breakpoints

Right-click any breakpoint glyph and choose Conditions. You can pause execution only when an expression is true:

order.CustomerId == 42 && order.Total > 1000

This is the difference between hitting F5 fifty times to find the one bad order and hitting it once. You can also break on a hit count ("every 100th iteration") or when a condition changes.

2. Tracepoints (the breakpoint that doesn't break)

In the same Conditions dialog, tick Actions and uncheck "Continue execution" — wait, do the opposite: leave it ticked. Now your breakpoint logs a message to Output instead of stopping:

Order {order.Id} processed by {Environment.CurrentManagedThreadId}

Curly braces evaluate expressions. You get printf-style debugging without editing code or recompiling. Perfect for "I just want to know how often this runs."

3. The Parallel Stacks window

Debug → Windows → Parallel Stacks. When your app hangs, this view shows every thread's call stack as a graph. The thread waiting on a lock and the thread holding it are obvious at a glance — much faster than clicking through the Threads window one by one.

4. DebuggerDisplay for your own types

Tired of expanding objects in the Watch window to see a useful field? Decorate the class:

[DebuggerDisplay("Order #{Id} ({Status}, {Total:C})")]
public class Order { ... }

Now the debugger shows Order #4711 (Shipped, $129.95) inline. Five seconds saved a hundred times a day.

5. Edit and Continue (and when not to use it)

You can change code while paused at a breakpoint and keep running. It's magical for tweaking a string or fixing an off-by-one without restarting a long startup sequence. It does not work for changes that affect type layout, async state machines in some configurations, or hot-reload-incompatible refactors. When in doubt, restart — false confidence here is worse than a 30-second restart.

6. The Immediate window is a REPL

With execution paused, the Immediate window (Ctrl+Alt+I) lets you call methods and inspect state on the fly:

> orders.Where(o => o.Total > 100).Count()
17
> service.Recalculate(orders[3])

You can call methods that have side effects — useful for forcing a state, scary if you do it on production data. Treat it like a sharp knife.

7. Exception settings: break on first chance

Debug → Windows → Exception Settings. By default, the debugger only stops on unhandled exceptions. Tick Common Language Runtime Exceptions and you'll catch them at the throw site, before any catch swallows them. Combined with conditional breakpoints, this is how you catch "the bug that gets logged but never reproduces."

Bonus shortcut. Ctrl+F10 runs to the cursor without setting a breakpoint. Useful when you want to skip ahead to a specific line just once.

Make these habits

None of these tricks are new — most have been in Visual Studio for a decade. The value comes from picking two or three and using them on every debugging session until they're muscle memory. The next stubborn bug will fall in half the time.

In our coaching tracks, debugger fluency is a recurring theme. If you'd like a pair-programming session walking through these on your codebase, reach out.