Sometimes, just dumping stuff out to the console is the best.
Especially in multi-threaded code, it can be the only way - hitting a breakpoint and stepping through causes other threads to time out in unnatural ways, and you're hosed tracking down things that wouldn't actually happen. It's not uncommon that I've run into issues where attaching a debugger or a profiler gets its hooks into something in the depths of whatever COM library I'm using that breaks it anyway (I love RedGate's performance profiler, but I can't use it for some things on Windows 10, because of some security something or other, while it works on 7 & 8...)
Log4net is, without a doubt, my favorite dependency. ColoredConsoleAppender FTW. Even better, if I take the slightest care with my log levels in code, I can tune the log output up and down just by tweaking the config. So I can leave full diagnostics in a release, tune things down to hide the verbosity, with minimal performance hit, and dial it back up to debug levels if I encounter an issue in production.
Especially in multi-threaded code, it can be the only way - hitting a breakpoint and stepping through causes other threads to time out in unnatural ways, and you're hosed tracking down things that wouldn't actually happen. It's not uncommon that I've run into issues where attaching a debugger or a profiler gets its hooks into something in the depths of whatever COM library I'm using that breaks it anyway (I love RedGate's performance profiler, but I can't use it for some things on Windows 10, because of some security something or other, while it works on 7 & 8...)
Log4net is, without a doubt, my favorite dependency. ColoredConsoleAppender FTW. Even better, if I take the slightest care with my log levels in code, I can tune the log output up and down just by tweaking the config. So I can leave full diagnostics in a release, tune things down to hide the verbosity, with minimal performance hit, and dial it back up to debug levels if I encounter an issue in production.