I use the following statement to print the name of the current function (for example, an event handler) to the Output window in Visual Studio (2010):
Debug.Write(MethodBase.GetCurrentMethod().Name);
If I put this inside a utility function such as DisplayFunctionName(), instead of the parent function that calls it, what is displayed each time is "DisplayFunctionName" - no surprises there!
I know there is no inlining in C#, but is there another solution for this situation, short of using 'snippets', so as not to have to duplicate such statements?
You can use the CallerMemberNameAttribute to display the caller's name.
public void WriteDebug(string message, [CallerMemberName] string memberName = "")
{
Debug.Write("[" + memberName + "] " + message);
}
There is also CallerLineNumberAttribute and CallerFilePathAttribute which you can use to include this information for more diagnostics. These attributes are described in detail on MSDN. Combined with [Conditional("DEBUG")] on the method, you have the capability to provide a lot of information during debugging that is completely eliminated in a release build.
I know there is no inlining in C#, but is there another solution for this situation, short of using 'snippets', so as not to have to duplicate such statements?
Note that this really has nothing to do directly with "inlining", as much as with getting the calling member's information for diagnostics. That being said, the JIT definitely performs inlining when your code is run, which is one of the major reasons C# has decent performance.
This requires Visual Studio 2012, as it uses new compiler features in that release to function.
If you are using an older compiler, the other alternative is to use StackTrace to pull out the stack trace information. This has a fairly significant performance impact, however, so it's not something I'd use in a tight loop, at least not in a production environment, though its still functional for diagnostics during debugging.
string callingMethodName = (new StackTrace()).GetFrame(1).GetMethod().Name;
Related
This is very dangerous so I wonder why it's allowed. Since I often need to switch between VB.NET and C# I sometimes add breakpoint-conditions like following:
foo = "bah"
I want to stop if the string variable foo is "bah, so the correct way was to use foo == "bah" instead of foo = "bah".
But it "works". You don't get any warnings or errors at compile- or runtime. But actually this modifies the variable foo, it makes it always "bah" even if it had a different value. Since that happens silently (the breakpoint never gets hit) it is incredibly dangerous.
Why is it allowed? Where is my error in reasoning (apart from confusing the C# and VB.NET syntax)? In C# (as opposed to VB.NET) an assignment statement returns the value that was assigned, so not a bool, but a string in this case. But a breakpoint condition has to be a bool if you check the box "Is True".
Here is a little sample "program" and screenshots from my (german) IDE:
static void Main()
{
string foo = "foo";
// breakpoint with assignment(foo = "bah") instead of comparison(foo == "bah"):
Console.WriteLine(foo); // bah, variable is changed from the breakpoint window
}
The breakpoint-condition dialog:
The code as image including the breakpoint:
It is an automatic consequence of C# syntax, common in the curly-braces language group. An assignment is also an expression, its result is the value of the right-hand side operand. The debugger does not object either to expressions having side-effects, nor would it be simple at all to suppress them. It could be blamed for not checking that the expression has a bool result, the debugger however does not have a full-blown C# language parser. This might well be fixed in VS2015 thanks to the Roslyn project. [Note: see addendum at the bottom].
Also the core reason that the curly-brace languages need a separate operator for equality, == vs =. Which in itself must be responsible for a billion dollar worth of bugs, every C programmer makes that mistake at least once.
VB.NET is different, assignment is a statement and the = token is valid for both assignment and comparison. You can tell from the debugger, it picks the equality operator instead and doesn't modify the variable.
Do keep in mind that this is actually useful. It lets you temporarily work around a bug, forcing the variable value and allowing you to continue debugging and focus on another problem. Or create a test condition. That's pretty useful. In a previous life-time, I wrote a compiler and debugger and implemented "trace points". Discovered the same scenario by accident and left it in place. It ran in a host that relied heavily on state machines, overriding the state variable while debugging was incredibly useful. The accident, no, not so useful :)
A note about what other SO users are observing, it depends on the debugging engine that you use. The relevant option in VS2013 is Tools + Options, Debugging, General, "Use Managed Compatibility Mode" checkbox. Same option exists in VS2012, it had a slightly different name (don't remember). When ticked you get an older debugging engine, one that is still compatible with C++/CLI. Same one as used in VS2010.
So that's a workaround for VS2013, untick the option to get the debugger to check that the expression produces a bool result. You get some more goodies with that new debugging engine, like seeing method return values and Edit+Continue support for 64-bit processes.
I can disagree about buggy nature of this behavior. Few examples where for debugging purposes in my life if was useful:
1. Other thread modifies something in your code.
2. Other service updated value in db
So I suppose for cases of synchronization it can be useful feature, but I agree that it can cause problems
In Visual Studio 2019, variable assignment expressions in Breakpoint conditions no longer work.
The expression will be evaluated for value, but side effects such as variable assignment are discarded.
https://developercommunity.visualstudio.com/content/problem/715716/variables-cannot-be-assigned-in-breakpoint-conditi.html
I frequently write C# code that has to use magic strings to express property names. Everyone knows the problems with magic strings. They are very difficult to refactor, they have no compile time checking, and often they lead to hard-to-diagnose issues. Yet C#/.NET uses them all over the place to represent property/class/method names.
This issue has persisted for years and years, and the only viable solution currently is to use an expression tree which is then parsed at run-time for the property name. This gets you satisfactory compile-time checking, but it complicates the code (requiring parameters of type Expression), and it incurs a run-time cost.
Does anyone know if there has ever been a feature consideration for C#/.NET to add compile-time reflection to overcome this pervasive problem?
It seems like it would be an easy addition to make, it would be a non-breaking change, and it would greatly benefit many developers. The typeof() operator already performs a form of compile-time reflection, so it seems like an operator nameof() (or something similar) would be very complimentary.
In addition, does anyone know of any potential issues with such a feature?
Thanks for the help.
Straight from the source - this is a blog post by a C# language designer, and the "User" in this post asks about the same questions as you and is answered. The author says there would be a need to specify a syntax for every metadata item you'd want to ask for and it's not trivial - ie. which overload you want, if you want "info-of" method and the method is overloaded? What if there are generics and explicit interface implementations involved? And so on. It turns out, while it wasn't deemed worthy of implementation in 2009 because of those reasons, we will get it in C# 6 in 2015 - see C# Language Design Notes for Jul 9, 2014 .
In C# 6.0, a new operator, nameof, is being added that will allow you to get the names of properties, classes, fields, events, and variables at compile time.
Link to the design notes
No more reflection for information the compiler already knows at design time!
I was having a similar problem. Only recently discovered that .NET Framework 4.5
has a feature called the Caller Info attributes. By using these, you can obtain information about the caller to a method at compile time. You can obtain file path of the source code, the line number in the source code, and the member name of the caller.
public void DoProcessing()
{
TraceMessage("Something happened.");
}
public void TraceMessage(string message,
[CallerMemberName] string memberName = "",
[CallerFilePath] string sourceFilePath = "",
[CallerLineNumber] int sourceLineNumber = 0)
{
Trace.WriteLine("message: " + message);
Trace.WriteLine("member name: " + memberName);
Trace.WriteLine("source file path: " + sourceFilePath);
Trace.WriteLine("source line number: " + sourceLineNumber);
}
Yet C#/.NET uses them all over the place to represent property/class/method names.
First off: I disagree. There are certain frameworks (WebForms, e.g.) that use magic strings all over the place, but the base libraries for C# and .NET tend to avoid such things remarkably well.
Secondly: In many instances where magic strings are used, ReSharper is able to recognize errors. This can help quite a bit.
Finally: What you're asking for may be possible via the Roslyn Compiler, which promises to provide "Compiling as a service."
Is it possible in C# to have some sort of check list when compiling to ensure parameters to functions are certain values?
For example, can I check that the parameter of this function is always greater than 10 at compile time?
void SomeFunction(1); <--- Compile error here
Take a look at Code Contracts. It's quite powerful; it can be used for both runtime checking and static verification. In addition, you can configure it to treat unproven contracts as compile-time warnings / errors.
void SomeFunction(int number)
{
Contract.Requires<ArgumentOutOfRangeException>(number > 10)
...
}
I don't know of any way to do this at compile time, you may be better off using an enumeration and only providing values in that enumeration that are above 10.
But, of course, this limits you to specific values which may not be what you want.
There are other options available to you such as:
runtime error, like throwing an exception.
runtime ignore, such as an if statement that exits the function for values that aren't in your range.
At a pinch, you could process the source code with another executable which examines values passed into you function, but that will only work for calls that can be bolied down to a constant argument. And, if they're constant arguments, you will catch them at runtime during the testing phase, long before your product gets within a hundred feet of a customer or beta tester. Unless your testing coverage is not up to scratch but then that's a different problem.
Otherwise, runtime checking is your only option.
If it isn't a very simple program I think this is impossible. It sounds related to the Halting problem.
I often find myself adding either concatonated strings or using a string formatter in my debug statements in log4net and log4j should I surround these debug statements with an "if debug" block to stop myself from wasting resources by processing these parameters even though the debug statement will not be printed out?
I would assume that checking if (isDebug) would be quicker and more efficient than having the string operations occuring, however it would lead to the program operating differently (faster) when the debug level is set higher than debug, which could mean that synchronisation problems that happen in production don't happen when I'm writing to the log.
for Java you can try log5j.
log4j:
log.debug("This thing broke: " + foo + " due to bar: " + bar + " on this thing: " + car);
log5j:
log.debug("This thing broke: %s due to bar: %s on this thing: %s", foo, bar, car);
log.debug("Exception #%d", aThrowable, exceptionsCount++);
I'd say it depends on how often the debug statement is called and how important performance is. Beware of premature optimization and all.
This question is answered in detail in the SLF4J FAQ. In short, use parameterized messages. For example, entry is an object, you can write:
Object entry = new SomeObject();
logger.debug("The entry is {}.", entry);
After evaluating whether to log or not, and only if the decision is affirmative, will the logger implementation format the message and replace the '{}' pair with the string value of entry. In other words, this form does not incur the cost of parameter construction in case the log statement is disabled.
The following two lines will yield the exact same output. However, the second form will outperform the first form by a factor of at least 30, in case of a disabled logging statement.
logger.debug("The new entry is "+entry+".");
logger.debug("The new entry is {}.", entry);
Have you measured how much extra time is taken concatenating these strings ? Given that the logging infrastructure will take the resultant messages, check whether they need to be dispatched to (possibly) multiple sinks, and then possibly write using some I/O, then you may not be gaining anything. My feeling is that unless your toString() mechanism is slow, this may be an optimisation too far.
I'm also wary of this approach in case someone writes something like this (and we know they shouldn't but I've seen this before)
if (Log.isDebugEnabled()) {
Log.debug("Received " + (items++) + " items");
}
and this will then work/fail depending on your logging level.
In log4j the following is recommended best practice:
if ( log.isDebugEnabled() )
{
log.debug("my " + var + " message";
}
This saves on system resources from the string concatenation etc. You are correct in your assumption that the program may perform slower when debug level is enabled, but that is to be expected: A system under observation is changed because it is under observation. Synchronization issues deal (mostly) with unlucky timing or variable visibility between threads, both of which will not be directly affected by an alteration of the debug level. You will still need to "play" with the system to reproduce multi-threaded problems.
We have adopted the practice to define a private static readonly boolean DEBUG variable in each class.
private static readonly log4net.ILogger LOG = log4net.LogManager.GetLogger();
private static readonly bool DEBUG = LOG.IsDebugEnabled;
each actual debug log line looks like this
if (DEBUG) LOG.Debug(...);
where ... can have arbitrary complexity and is only evaluated when debugging is required.
See: http://logging.apache.org/log4net/release/faq.html, the answer to "What is REALLY the FASTEST way of (not) logging?"
This works for us since we only read the log config at startup.
Since we have at least one debug statement per function call, we felt that having to write if (DEBUG) was worth the effort to get maximum performance with debuging switched off. We did some measurements with debugging switched on and off and found performance increases between 10 and 20%. We haven't measured what the effect of the if (DEBUG) was.
By the way: we only do this for debug messages. Warnings, informationals and errors are produced directly via LOG.Warn, etc.
Try slf4j (http://www.slf4j.org/). You write statements like:
log.fine("Foo completed operation {} on widget {}", operation, widget);
The log message is not assembled inside the library until the log level has been determined to be high enough. I find this the best answer.
(This is a lot like the log5j solution above.)
With C#, we've started using delegates for expensive log statements. It's only called if the log level is high enough:
log.Debug(()=> "Getting the value " + SomeValue() " is expensive!");
This prevents logging bugs where the level checked for is different to the level logged at, ie:
if(log.Level == Level.Info)
log.Debug("Getting the value " + SomeValue() " is expensive!");
and I find it much more readable.
[Edit] If that was downvoted for not applying to Log4Net - it is trivial to write a wrapper around Log4Net to do this.
Conditional compilation works with final constants, which are static final variables. A class might define the constant like this:
private static final boolean DEBUG = false;
With such a constant defined, any code within an:
if (DEBUG) {
// code
}
is not actually compiled into the class file. To activate debugging for the class, it is only necessary to change the value of the constant to true and recompile the class (you can have two version of your binaries, one for development and one for production).
However this is solution is suboptimal for several reasons.
I tend to wrap all calls to debug in an isDebug statement. I don't think that's a premature optimization, it's just good practice.
Worrying about the app running at different speeds isn't really sensible, as the load on the processor can / will influence your app more then the debugging code.
Look for the externalized log level from log4j config file. That way you have the option to switch on or off logs based on your environment (and avoid all those string concatinations).
if(log.isDebugEnabled())
{
log.debug("Debug message");
}
I want to add logging or tracing to my C# application but I don't want the overhead of formatting the string or calculating values to be logged if the log verbosity level is set so low that the message will not be logged.
In C++, you can use the preprocessor to define macros that will prevent code from being executed at all like this:
#define VLOG(level,expr) if (level >= g_log.verbosity) { g_log.output << expr; }
Used like this:
VLOG(5,"Expensive function call returns " << ExpensiveFunctionCall());
How do you do that in C#?
I've read the Microsoft docs explaining the Trace and Debug facilities here, and they claim that using #undef DEBUG and #undef TRACE removes all tracing and debugging code from the produced executable, but does it really remove the whole call? Meaning, if I write
System.Diagnostics.Trace.WriteLineIf(g_log.verbosity>=5,ExpensiveFunctionCall());
it won't call my expensive function if I undefine TRACE? Or does make the call, then decide it won't trace anything?
Anyway, even if it does remove it, this is inferior to the C++ macro because I can't make that big ugly call look like my simple VLOG() call in C++ and still avoid evaluating parameters, can I? Nor can I avoid the overhead by defining the verbosity lower at runtime like I can in C++, right?
To answer one of your questions, all method calls that must evaluate in order to call Trace.WriteLine (or its siblings/cousins) do not get called if Trace.WriteLine is compiled out. So go ahead and put your expensive method calls in directly as parameters to the Trace call and it will be removed at compile-time if you don't define the TRACE symbol.
Now for your other question regarding changing your verbosity at runtime. The trick here is that Trace.WriteLine and similar methods take 'params object[] args' for their string formatting arguments. Only when the string is actually emitted (when verbosity is set sufficiently high) does the method call ToString on those objects to get a string out of them. So a trick I often play is to pass objects rather than fully-assembled strings to these methods, and leave the string creation in the ToString of the object I pass in. That way the runtime performance tax is only paid when logging is actually occurring, and it gives you the freedom to change verbosity without recompiling your app.
A solution that has worked for me is using a singleton class. It can expose your logging functions and you can control its behavior efficiently. Lets call the class 'AppLogger'. Her is an example
public class AppLogger
{
public void WriteLine(String format, params object[] args)
{
if ( LoggingEnabled )
{
Console.WriteLine( format, args );
}
}
}
Note, the Singleton stuff is left out of the above example. There are TONS of good examples out the tubes. NOw the interesting thing is how to support multi-threading. I've done it like this: (abbreviated for brevity, hahahaha)
public static void WriteLine( String format, params object[] args )
{
if ( TheInstance != null )
{
TheInstance.TheCreatingThreadDispatcher.BeginInvoke( Instance.WriteLine_Signal, format, args );
}
}
In this way, any thread can log and the messages are handled on the original creating thread. Or you could create a special thread just for handling logging output.
ConditionalAttribute is your best friend. The call will be completely removed (as though call sites were #if'd) when the #define is not set.
EDIT: someone put this in a comment (thanks!), but worth noting in the main answer body:
All the methods of Trace class are decorated with Conditional("TRACE"). Just saw this using reflector.
Which means Trace.Blah(...expensive...) does completely disappear if TRACE is not defined.
All the info about Conditional(Trace) is good - but I assume your real question is that you want to leave the Trace calls in your production code but (usually) disable them at run-time unless you experience a problem.
If you're using TraceSource's (which I believe you should, rather than calling Trace directly because it gives you more fine-grained control over tracing at a component-level at run-time), you can do something like this:
if (Component1TraceSource.ShouldTrace(TraceEventType.Verbose))
OutputExpensiveTraceInformation()
This assumes you are able to isolate the tracing parameters in another function (i.e. they mostly depend on members of the current class rather than expensive operations on the parameters to the function in which this code is in).
The advantage of this approach is because the JITer compiles on a function-by-function basis as it needs to, if the "if" evaluates to false, the function will not only not be called - it won't even be JITed. The downside is (a) you've separated knowledge of the tracing level between this call and the function OutputExpensiveTraceInformation (so if you e.g. change the TraceEventType there to be TraceEventType.Information, for instance, it won't work because you'll never even call it unless the TraceSource is enabled for Verbose level tracing in this example) and (b) it's more code to write.
This is a case where it would seem that a C-like preprocessor would help (since it could make sure, for instance,that the parameter to ShouldTrace and to the eventual TraceEvent call are the same), but I understand why C# doesn't include that.
Andrew's suggestion of isolating expensive operations in the .ToString methods of the objects you pass to TraceEvent is also a good one; in that case, you could for instance develop an object which is just used for Trace to which you pass the objects you want to build an expensive string representation of and isolate that code in the ToString method of the trace object rather than doing it in the parameter list to the TraceEvent call (which will cause it to be executed even if the TraceLevel is not enabled at run-time).
Hope this helps.
have you tried a sophisticated logging api like log4net (http://logging.apache.org/log4net/index.html)?
Two of these answers (Andrew Arnott's and Brian's) did answer part of my question. The ConditionalAttribute that is applied to the Trace and Debug class methods causes all calls to the methods to be removed if TRACE or DEBUG are #undef'd, including the expensive parameter evaluation. Thanks!
For the second part, whether you can completely remove all calls at runtime, not at compile time, I found the answer in the log4net fac. According to them, if you set a readonly property at startup time, the runtime will compile away all calls that don't pass the test! This doesn't let you change it after startup but that's fine, it's better than removing them at compile time.
For your comment
"because I can't make that big ugly call look like my simple VLOG() call in C++ " - You could add a using statement as example below.
using System.Diagnostics;
....
Trace.WriteLineIf(.....)
As I understand, it will remove lines containing Trace, if you undefine the Trace symbol.
I'm not sure, but you can find out the answer yourself.
Make it a REALLY expensive function (like Thread.Sleep(10000)) and time the call. If it takes a very long time, then it's calling your function anyway.
(You can wrap the Trace.WriteLineIf() call with #if TRACE and #endif and test it again for a base comparison.)
It will invoke the expensive call because it might have side effects that are desired.
What you can do is decorate your expensive method with a [Conditional("TRACE")] or [Conditional("DEBUG")] attribute. The method will not be compiled into the final executable if the DEBUG or TRACE constant is not defined, nor will any calls to execute the expensive method.