Professional Visual Studio
Tips, Tricks, and Best Practices for professional .net developers

We’re quickly approaching the last of the Debugger attributes in the System.Diagnostics namespace. After this week there are only two more to go, but don’t despair, because I’ve saved the best till last. However for now let’s take a look at the DebuggerNonUserCode and DebuggerStepperBoundary attributes.

The DebuggerNonUserCode attribute has the same effect as using both the DebuggerHidden and DebuggerStepThrough attributes at the same time. In the default Visual Studio configuration, code marked with this attribute will appear as external code in the call stack as shown below. As with the DebuggerStepThrough attribute, breakpoints cannot be set in blocks of code marked with this attribute. Stepping through code will step into any code called by that block of code in the same way it does for the DebuggerHidden attribute.

Call stack showing the effect of the DebuggerNonUserCode attribute

Code that is marked with the DebuggerNonUserCode attribute will be visible in the call stack if you disable the Just My Code option under Tools->Options->Debugger->Enable Just My Code (Managed Only).

DebuggerStepperBoundary is probably the most obscure of all of the Debugger attributes, as it only comes into effect under quite specific conditions. It is used to avoid a misleading debugging experience that can occur when a context switch is made on a thread within the boundaries of the DebuggerNonUserCode attribute. It is entirely possible in this scenario that the next user-supplied code module stepped into may not actually relate to the code that was in the process of being debugged. To avoid this undesirable situation, the DebuggerStepperBoundary, when encountered under this scenario, will escape from stepping through code to running code.

As with all of the debugger attributes, both the DebuggerNonUserCode and DebuggerStepperBoundary attributes are ignored by the CLR and as such have no affect during normal execution. So you do not need to worry about any implications of leaving any of these attributes in place in production code.

We have 10 copies of our book, Professional Visual Studio 2008, to give away. Rather than hand them all out at once, we’ve decided to spread things out a little, and give away 2 books per month for the next 5 months.

To be in the running you need to either:

At the end of each month we will draw two winners at random from those who participated during that month.

This competition is open to everyone (regardless of where you reside). If you are lucky enough to be drawn as a winner, we will contact you via email before announcing the winners. Winners will need to provide us with their name, telephone number, and shipping address.

This competition has been made possible due to the generosity of our publisher, Wiley Publishing.

Good luck!

The DebuggerStepThrough attribute is another of the debugger attributes that should be used carefully and only on well-tested code. Like the DebuggerHidden attribute, when the DebuggerStepThrough attribute is applied to a piece of code, that code is stepped over during debugging.

Similar to the DebuggerHidden attribute, breakpoints cannot be set within a block of code marked with the DebuggerStepThrough attribute. However, within the call stack the attributed code will be marked as external code. For example, consider the following code snippet where the DebuggerStepThrough attribute has been set on HiddenMethod:

private void ClickHandler(object sender, EventArgs e)
{
   HiddenMethod();
}

[DebuggerStepThrough()]
public void HiddenMethod()
{
   Console.WriteLine("Can't set a breakpoint here");
   NotSoHiddenMethod();
}

public void NotSoHiddenMethod()
{
   Console.WriteLine("Can set a breakpoint here!");
}

If you run this code with a breakpoint set in NotSoHiddenMethod, the call stack will appear as shown below:

Call stack showing the effect of the DebuggerStepThrough attribute

Visual Studio 2008 supports the Just My Code option, configurable from the Debugging node in the Options dialog (select Tools > Options). Unchecking this option makes all code contained within your application appear in the call stack, as shown below. This includes designer and other generated code that you might not want to debug. Once this option is unchecked, breakpoints can also be set in blocks of code marked with this attribute.

Call stack showing the effect of the DebuggerStepThrough attribute combined with the Just My Code setting

DebuggerStepThrough is very useful when working with code that calls a lot of properties, for example, if you are calling a method that passes in a large number of properties as parameters. If you add the DebuggerStepThrough attribute to all the properties, and then you won’t step into all of the properties when debugging the method call.

I’ve been speaking with Wrox/Wiley about some marketing and promotional activities around Professional Visual Studio 2008. One of the things that has come up is the option of making a sample chapter available as a free download. Chapter 1 is already available for download from Wrox, but any one of the other chapters could be made available.

So we’re asking for suggestions as to which chapter we should make available. You can view the list of chapters here, or download the full Table of Contents from Wrox. You should let us know which chapter you’d like to see, by commenting on this post or sending us an email via our contact page.

We’ll also have an announcement in the near future about how you can win free copies of the book as part of a promotional giveaway. This will be open to those who live outside of North America. More details to come very soon.

Continuing on with an exploration of the various debugger attributes found in the System.Diagnostics namespace, this week I’d like to present the DebuggerHidden attribute.

This is something you probably only want to apply to VERY well tested code. Code marked with the DebuggerHidden attribute will be stepped over during debugging, and the method call will not even appear in the Call Stack window. However, if some code marked with this attribute makes a call to another method, the debugger steps into that method.

It’s also worth noting that any breakpoints that have been set in code marked with the DebuggerHidden attribute will be ignored. For example, in the following code snippet, a breakpoint can be set in both ClickHandler and NotSoHiddenMethod:

private void ClickHandler(object sender, EventArgs e)
{
   HiddenMethod();
}

[DebuggerHidden()]
public void HiddenMethod()
{
   Console.WriteLine("Can't set a breakpoint here");
   NotSoHiddenMethod();
}

public void NotSoHiddenMethod()
{
   Console.WriteLine("Can set a breakpoint here!");
}

If you step through this code, the debugger goes from the call to HiddenMethod in the ClickHandler method straight to the NotSoHiddenMethod. The call stack at this point is shown below, and you can see that HiddenMethod does not appear in the stack.

Call stack showing the effect of the DebuggerHidden attribute

As with all of the System.Diagnostic attributes, the CLR will ignore this, so you will still see the method call in the stack trace of any an exceptions thrown at runtime.

Yesterday Microsoft Visual Studio Extensibility team announced a new update in Visual Studio 2008 SDK and released version 1.1 to public.

For VSX developers, this is important news because there are some major updates to improve the extensibility features especially around Visual Studio Shell development. This new version works on .NET Framework 3.5 and Visual Studio 2008 Service Pack 1.

Quan To has outlined these updates on VSX team blog but major updates are a reduction in the size of VS Shell package installers that no longer hold .NET Framework 3.5 data and also there is an update that lets you develop VS Shell applications as a normal Windows user that wasn’t possible before.

You can download Visual Studio 2008 SDK 1.1 from here.

Hands up if you think the Output window is annoying in its default configuration. I’m referring to how every time you run a build the Output window pops up and interrupts you, obscuring half the code window. Sometimes I get the feeling that it was starved for attention as a child ;-)

Output Window in the way

There are a couple of easy solutions to this problem. Firstly, you can simply stop the Output window from being automatically shown during a build. Open the Options dialog (Tools->Options) and select Projects and Solutions. You will find an option under here called Show Output window when build starts. Simply uncheck this option and you will never be interrupted again.

However many people, myself included, have found that the Output window is actually quite useful to have around. If that’s the case, you may want to have it automatically open, but in a different way. My suggestion is to try changing the Output window to display as a Tabbed Document. Simply right-click on the window title bar and select Tabbed Document as shown below:

Output window to Tabbed Document

Once you’ve made this change, the Output window will open at the same level as the active code window. It will still come to the foreground, which I find useful, however to me it feels like it does this in a much more natural and frictionless way. I’d be very interested to hear whether anyone else prefers this also.

Output window as Tabbed Document

To wrap up this post, here’s a couple more things about the Output window that are useful to know:

  • Press Ctrl+Alt+O to display and bring the Output window into focus;
  • Press Ctrl+S when the Output window has focus to save the text in the Output window to an external file;
  • If you do choose to not automatically display the Output window during a build, you can redirect all Diagnostic messages (e.g. Debug.Print) to the Immediate Window, as mentioned in my first Debugging Tip of the Week.

Last week, we started to explore the first of the Debugger attributes that are found in the System.Diagnostics namespace by looking at the DebuggerBrowsable attribute. I’d like to continue that theme this week with the DebuggerDisplay attribute.

No doubt you’ve seen that hovering your mouse over a variable while you are in Break mode will cause a tooltip to be displayed, which shows the type of object you are hovering over. You can see this below, where the datatip for a Customer object is shown.

Customer class with a default datatip

Unfortunately this information is not particularly useful, as most of the time you have a fairly good idea about the type of object you are dealing with. It would be better for this single line to contain more useful information about the object, as is the case with simple types such as strings or integers where the actual value is displayed.

This is where the DebuggerDisplay attribute comes in handy. It can be used to change this single line representation of the object from the default full class name. The attribute takes a single parameter, which is a String. The format of this string can include the { and } braces, which can contain a field, property, or method that returns a value.

For example, you could apply the DebuggerDisplay attribute to the Customer class as follows:

[DebuggerDisplay("Customer {CustomerName} has {Orders.Count} orders")]
public class Customer

If you apply the attribute in this way, it will result in the following datatip:

Customer class with DebuggerDisplay attribute

If you are a C# developer, then in addition to specifying properties and methods in the DebuggerDisplay format string, you can also include a general expression within the braces. For example, the following attribute shows how you could use an expression with a ternary operator:

[DebuggerDisplay("Customer {CustomerName} has orders? {(Orders.Count > 0) ? \"Yes\" : \"No\"}")]

Which would result in the following datatip:

Customer class showing datatip with DebuggerDisplay attribute expression

One final thing to note, in addition to Classes, the DebuggerDisplay attribute can be applied to any Struct, Delegate, Enumeration, Field, Property, or even an entire Assembly.

By now you’ve probably heard that Service Pack 1 for Visual Studio 2008 and .NET Framework 3.5 has been released. You can download it as a single setup package for both Visual Studio and .NET Framework 3.5, or just for the .NET Framework 3.5. It takes a while to complete the install, so you may want to kick it off at the end of the day, rather than tie up your machine for a few hours.

If you’ve installed any beta stuff (i.e. Silverlight 2 Beta, Framework Source Code perf patch, SP1 Beta) you’ll also need to download and run the Visual Studio 2008 Service Pack 1 Preparation Tool. The installer will check for these antirequisites and prompt you to run the preparation tool if necessary.

Scott Hansleman has a nice roundup of what Service Pack 1 includes for WinForms, WebForms, and the rest the Framework.

I would particularly encourage any web developers to install SP1, as there are a large number of important fixes and enhancements specifically targeting web development. You can find a nice comprehensive overview of these on the Visual Web Developer Team Blog.

In my latest instalment of the Debugging tip of the week, I’d like to introduce the debugging attributes. These handy attributes, found in the System.Diagnostics namespace, can be applied to your source code in order to control the way the debugger steps through it. Some of the debugging attributes can also be used to customise the data tips that appear when you hover over a variable in Break mode, or view it in a Watch window.

The first attribute we will cover is the DebuggerBrowsable attribute. This attribute takes a DebuggerBrowsableState enumeration value as a parameter that determines how the member is displayed in the variable tree. In the following code snippet, the field Orders in the Customer class is set to Collapsed:

using System.Diagnostics;

public class Customer
{
   [DebuggerBrowsable(DebuggerBrowsableState.Collapsed)]
   public List<Order> Orders;
}

Collapsed is the default DebuggerBrowsableState that you would normally see in Visual Studio. If you apply this to a member then it will be displayed, but not expanded by default, as shown below.

DebuggerBrowsableState.Collapsed

The following shows the same snippet with DebuggerBrowsable set to the RootHidden value. In this case the actual Orders item does not appear as a top-level entry in the data window, just the contents of the collection.

DebuggerBrowsableState.RootHidden

Finally, the Never value will hide the member completely from the data window. This can be quite useful if you want to hide your private properties. You can see the effect of this below, where the Orders member does not appear at all.

DebuggerBrowsableState.Never

In .NET Framework 2.0, the DebuggerBrowsable attribute is only interpreted by the C# debugger and has no effect when it is applied to Visual Basic code. This limitation has been removed in newer versions of the .NET Framework.

« Previous PageNext Page »


About this site

Professional Visual Studio aims to provide tips and tricks, traps to avoid, and industry best practices from experienced .NET developers on using Visual Studio in the most effective way possible.

Copyright © 2007-2012 David Gardner, Keyvan Nayyeri, and Nick Randolph. All rights reserved.
Blog | Archives | Books | About | Contact