Debug.WriteLine in release build
Asked Answered
T

5

73

Is there a way to use Debug.WriteLine in a release build without defining DEBUG?

Timberlake answered 24/3, 2011 at 12:58 Comment(2)
Definining _DEBUG in the release build has far fewer side effects than you may fear. Certainly don't hesitate to define it when troubleshooting a release build problem.Footpad
Use .NET Tracing (preferably TraceSources). It's much more flexible.Leslie
V
63

No, but you can use the Trace in release by defining TRACE and using Trace.WriteLine. Have a look here:

https://support.microsoft.com/en-us/help/815788/how-to-trace-and-debug-in-visual-c

Vivisectionist answered 24/3, 2011 at 13:2 Comment(1)
Perfect. I just want to use SysInternals DebugViewer and Trace.WriteLine seems to get picked up by itTimberlake
U
50

No. If you don't define the DEBUG preprocessor symbol, any calls to Debug.* will be removed by the compiler due to the [Conditional("DEBUG")] attribute being applied.

You might want to consider Trace.WriteLine or other logging techniques though.

Uncut answered 24/3, 2011 at 13:1 Comment(0)
W
22

While you still have to define DEBUG - you don't have to do it assembly wide. You can define it only in the source files that you want. So if you want debug logging from a particular class you can define DEBUG just for that source file.

#define DEBUG
using System.Diagnostics;

...

class Logger
{
    void Log( string msg ){ Debug.WriteLine( msg ); }
}
Wilfredowilfrid answered 3/4, 2012 at 6:12 Comment(1)
I like this method the best. The #define only applies to the source file and not the whole project. This is a good way to release a library in a nuget (say) that can be reused by other projects when they are in DEBUG mode for doing Debug.Writeline with custom outcomes likes timestamps and exception handling, etc.Spill
M
5

Yes. You can, as mentioned in the above comments use TRACE, or without defining any compile time constants, by using Expression Trees.

        var p = Expression.Parameter(typeof(string), "text");
        var callExp =
            Expression.Call(
              typeof(System.Diagnostics.Debug).GetRuntimeMethod(
                   "WriteLine", new [] { typeof(string) }),
              p);
        Action<string> compiledAction = Expression.Lambda<Action<string>>(
                                         callExp, p)
                                         .Compile();

After this, you can invoke the Debug.WriteLine anytime, by calling

        compiledAction("Debug text");

You're essentially tricking the compiler by not having a static method call, but instead dynamically constructing it at run-time.

There is no performance-hit since, the action is compiled and re-used.

This is how I wrote a DebugLogger in SharpLog.

You may take a look at the source code here, if it interests you: https://github.com/prasannavl/SharpLog/blob/master/SharpLog/DebugLogger.cs

Mongeau answered 15/5, 2014 at 4:24 Comment(2)
I don't know if I'd ever recommend this .. but it's an "interesting" solution.Leslie
I wouldn't recommend it, in general. But if the production code, is anyway going to print out the debug values, then it makes no difference if its Debug.WriteLine or the compiled Lambda, which is almost just a (() => Debug.WriteLine()) without the JIT optimizations in play.Mongeau
P
1

Debugger.Log(0, null, "Your string here"); could be an alternative, it is used internally by Debug.Write and it also works in Release.

Prefix answered 8/11, 2022 at 19:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.