It so happened that I recorded a quick 30-minutes video (screencast) showing the new features in the language and the IDE – and I did all this on a recent internal build of Visual Studio 2010, which has the WPF UI enabled. The video is very basic, I don’t go into any details, it’s mainly a quick overview and how features look like:
You can also download or view the .wmv file here: http://guilabs.de/video/CSharp4.wmv
Features covered:
I don’t remember seeing any explicit guidelines on whitespace formatting for C# programs, however it seems that experienced C# developers all format their C# code files in a very similar fashion, as if there are some implicit but widely-accepted rules. In this post, I’ll try to formalize my own rules that I use intuitively when I format C# code. I’ll add more to it as I discover new stuff and correct things based on your feedback.
No two consecutive empty lines
Bad:
1: static void Main(string[] args)
2: {
3: Main(null);
4: }
5:
6:
7: static void Foo()
8: {
9: Foo();
10: }
No empty line before a closing curly
1: Main(null);
2:
3: }
No empty line after an opening curly
1: class Program
3:
4: static void Main(string[] args)
One empty line between same level type declarations
1: namespace Animals
3: class Animal
4: {
5: }
7: class Giraffe : Animal
9: }
One empty line between members of a type
1: class Animal
3: public Animal()
7: public void Eat(object food)
10:
11: public string Name { get; set; }
12: }
Whereas it’s OK to group single-line members:
1: class Customer
3: public string Name { get; set; }
4: public int Age { get; set; }
5: public string EMail { get; set; }
7: public void Notify(string message)
However every multi-line member must be surrounded by an empty line unless it’s the first or the last member, in which case there shouldn’t be a line between the member and the curly brace.
One empty line after #region and before #endregion
Usually #region should be treated as if it were the first construct from it’s content (in this example, a type member):
3: #region Public properties
4:
5: public string Name { get; set; }
6: public int Age { get; set; }
7: public string EMail { get; set; }
8:
9: #endregion
11: public void Notify(string message)
12: {
13: }
14: }
Within a #region, it’s contents should be separated from the #region/#endregion by a single empty line. Usually #regions contain type members or whole types, less often parts of a method body.
I think these are the major rules that come into mind for now. If I remember more, I’ll update this post. Also, definitely feel free to contribute any corrections/additions and I’ll update the post too. Thanks!
I’ve just found and fixed a globalization bug in our test infrastructure where a feature of our testcase management system (resetting a testcase to re-run on a lab machine) just wouldn’t work on a Russian OS. Fortunately, the call stack was easy to investigate: (sorry it’s in Russian - globalization, what can you do…)
System.InvalidCastException: Приведение строки "2.0" к типу "Double" является недопустимым. ---> System.FormatException: Входная строка имела неверный формат. в Microsoft.VisualBasic.CompilerServices.Conversions.ParseDouble(String Value, NumberFormatInfo NumberFormat) в Microsoft.VisualBasic.CompilerServices.Conversions.ToDouble(String Value, NumberFormatInfo NumberFormat) --- Конец трассировки внутреннего стека исключений --- в Microsoft.VisualBasic.CompilerServices.Conversions.ToDouble(String Value, NumberFormatInfo NumberFormat) в Microsoft.VisualBasic.CompilerServices.Conversions.ToDouble(String Value) в XXXXXXXX.Utilities.DotNetFramework.IsDotNetFramework35HigherInstalled() в XXXXXXXX.Result.BulkResetResultsHelper(...
This essentially says: cannot convert a string “2.0” to double. Here’s the problem line of code (VB):
version = CDbl(numbers(0) & "." & numbers(1))
and here’s a fix:
version = System.Double.Parse(numbers(0) & "." & numbers(1), System.Globalization.CultureInfo.InvariantCulture)
The original code made an incorrect assumption that the decimal separator in the current culture is the ‘.’ character. However on German, Russian, Italian and some other OSs the default decimal separator is a ‘,’, not a ‘.’. By default, string operations use the current locale (and hence expect a comma as a decimal separator), so if you want to compose a string using a dot and convert it to a double, you have to use InvariantCulture, which uses a dot.
I’ve seen this error quite a lot of times – this is probably the most common globalization bug out there. Keep in mind, it’s 21st century out there, it’s likely that your software will be used all over the world on all possible combinations of operating systems, languages, locales, encodings, RTL etc.
A good read on this topic would be Jeffrey Richter’s CLR via C#, chapter 11 (Chars, Strings, and Working with Text), pages 264-268).
One of the ways we test Visual Studio is by automating the devenv.exe process using a library called DTE (Design Time Extensibility). To use this library from your .NET application, you’ll need to add a reference to the EnvDTE assembly (which is usually available on the .NET tab of the Add Reference dialog).
Starting Visual Studio using DTE
Here's a simple code snippet that starts Visual Studio and displays its main window:
using System; using EnvDTE; class Program { static void Main(string[] args) { Type visualStudioType = Type.GetTypeFromProgID("VisualStudio.DTE.9.0"); DTE dte = Activator.CreateInstance(visualStudioType) as DTE; dte.MainWindow.Visible = true; } }
When the VS object is being created, a VS process (devenv.exe) starts in the background. You can make its main window visible using dte.MainWindow.Visible = true;
Note that when the parent process (your program) ends, VS will close with it as well.
To get an instance of an already running VS process, you can use the following snippet:
EnvDTE80.DTE2 dte2 = (EnvDTE80.DTE2) System.Runtime.InteropServices.Marshal.GetActiveObject("VisualStudio.DTE.9.0");
This snippet also demonstrates using DTE2, a newer version of the DTE interface that provides additional functionality.
DTE interface
Since DTE is COM based, we need to get the type that represents DTE from a well-known ProgID (“VisualStudio.DTE.9.0” that can be found in the registry). Once we have that type, we create an instance of it using Activator and cast it to the DTE interface. Contrary to what the name suggests, DTE is actually an interface and not a class:
namespace EnvDTE { [CoClass(typeof(DTEClass))] [Guid("04A72314-32E9-48E2-9B87-A63603454F3E")] public interface DTE : _DTE { } }
DTE commands
Now that you have DTE in your hands, you can do a whole lot of stuff, for example, execute a command:
dte.ExecuteCommand("File.OpenFile", "");
This one will execute the File.OpenFile command to display the open file dialog. There are plenty more Visual Studio commands that are really useful if you want to automate Visual Studio. You can look up a VS command from the Command Window: View –> Other Windows –> Command Window. Just start typing there and it will offer a completion list:
Also, you can use the Customize dialog (right-click on any VS menu) to get an idea of what commands are available:
Finally, you can see what command corresponds to an action if you start recording a macro, then just do an action manually, and then view the source code for that macro. As the macro is being recorded, VS registers all DTE command calls and writes them down in VBA source code. For example, ever wondered what command corresponds to the Rename refactoring? Record it and view the macro source, you’ll find out that there is a Refactor.Rename command.
Other DTE API
Apart from DTE.ExecuteCommand, there are a lot of other APIs to control the editor, ActiveDocument, ActiveWindow, Application, Debugger, Documents, ItemOperations, Solution, SourceControl, etc.
However this deserves a separate post by itself. Who knows, if there is popular demand on how to automate Visual Studio, I might start a series of blog posts about that. However, for now, I’ll just link to MSDN articles on DTE:
If you use WPF/Silverlight and prefer working with XAML only (i.e. no visual designer), you can significantly, I repeat, significantly speed-up the XAML editor. Check out this tip from Fabrice Marguerie: Life changer XAML tip for Visual Studio
I found an interesting bug recently which resulted from a pretty weird constellation of the following Visual Studio features:
Here's the screenshot of the bug:
If you pasted this code in a recent VS 2010 build, the navigation bar (two comboboxes above) would grow to accomodate the full text of the Main method. Why?
Here's what happens:
We hope to fix the bug before VS 2010 Beta 2 (probably not Beta1 because it's a low impact low priority).
Big thanks to He,YuanHui who has translated my debugging tutorial into Chinese:
http://www.cnblogs.com/khler/archive/2009/02/08/1386462.html
Enjoy!
Well, I've been tagged in a chain-letter-blogging game again. This time, Chris "I-like-to-put-ugly-monsters-on-the-frontcovers-of-my-books-to-at-least-partially-distract-readers-from-great-content" Smith tagged me in his New Years resolutions post. It's February, but I think it's better late than never. So here it goes:
Make sure VS 2010 rocks!
I'll try to do my part and make sure that our language service works as expected and the features are pleasant to work with. I'll also try to make sure other teams don't miss obvious bugs (yes, Editor, Shell and Project System, I'm looking at you!) Given the fact that I keep finding crashes in the XAML designer, I'll keep an eye on them as well. Oh and the debugger, of course.
Learn MEF
I plan to read MEF sources and actually play with it. It's 21 century out there, nowadays you *need* a dependency injection/component framework.
Learn DLR
Especially DLR hosting. Would be fun to build an expression evaluator/function graph plotter into my Live Geometry Silverlight app.
Read more of the product code
I definitely should read more of the VS source, especially since more and more of it gets rewritten in managed code. We're building a managed compiler and rewriting the language service in managed code, it would be great to follow the API design there. It's super important to get the API surface right. I'll maybe start playing with it early on and build some sample apps/add-ins to see how the API feels.
Read more blogs
and catch up on all those starred and flagged items. I plan to read all of Cyrus, all of Wes and all of Eric, for a start. I need to catch up on Jon's early posts as well. Also, I still hope Wes starts blogging again. Same for Dustin (although I do understand how busy Dustin is in his new role...)
Gym
Continue ignoring it. I'll at least be honest to myself. I will still exercise regularly. Once in three months is regular, isn't it?
Is there anything else that I've missed? :-P
In my recent post about coding styles one particular thing provoked the majority of feedback and discussions: the ForEach extension method on IEnumerable<T>. Justin Etheredge has a good post about this method here. StackOverflow.com also has a good question: Why is there not a ForEach extension method on the IEnumerable interface?
Note: If you’d like this method to be added to .NET 4.0, go vote here: https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=279093
Recently I also went ahead and logged a suggestion against the BCL team to add this method in .NET 4.0, and got some feedback from Melitta Andersen and Justin van Patten. Essentially, the BCL team’s considerations boil down to what we’ve discussed in my recent post:
Mads Torgersen (representing the language design team) was also reluctant about adding this method because of similar concerns (functional impurity etc). I myself in my previous post was enumerating various downsides of using this method.
And still I think we should add it.
My thinking is the following. The ultimate purpose of the BCL is to help avoid code duplication by introducing a common reusable set of functionality so that people don’t have to reinvent the wheel by writing their own collections, sorters, etc. A lot of people will use ForEach anyway, and if we don’t provide it in the framework, they will have to re-implement it in every new project. Also, by providing the ForEach method out of the box, we’re not forcing anyone to actually go ahead and use it – people will still have the choice and be warned about the downsides of ForEach. It’s just when they will use it anyway (and this happens a lot), they will be able to consume a ready-made one. The use of having it (in my opinion) by far overweights the downsides of using it inappropriately.
ForEach looks really good with very simple snippets, such as:
myStrings.ForEach(Console.WriteLine);
Some developers forget that you can use this shorter syntax instead of:
myStrings.ForEach(s => Console.WriteLine(s));
Another ForEach advantage is that it allows you to extract the body of the loop into a separate place and reuse it by just calling into it.
Also, given the fact that List<T> already has it, it seems unfair that IEnumerable<T> doesn’t. This is an unnecessary limitation (that’s what I think).
Chris Tavares says:
I suspect the reason that this didn't exist before is that you can't use it from VB. VB only support lambda expressions, while the foreach method requires a lambda *statement*.
Well the good news is that we are introducing statement lamdbas in VB 10.0 so this shouldn’t be an issue at all.
I’m also pretty sure that one can also overcome the debugging difficulties of ForEach with tooling support, such as [DebuggerStepThrough] and “Step Into Specific”. Debugging problems are not language/libraries problem per se, it’s a tooling problem, and tooling should always be fixed/improved to satisfy languages and libraries.
A lot of people are asking for the ForEach extension method – this is probably one most wanted piece of API:
My questions for you folks are:
There are also variations on this extension method:
If you ask me, only the simplest overload should be added, because Select is a better choice for chaining calls. Also this would encourage people to use the method in the simplest scenarios, where the downsides of doing so are negligible.
Finally, one argument I have is that googling “foreach extension method” yields 1 590 000 results, which I think is a pretty good indication that the feature has high demand.
Sooner or later you may run into a situation where you need to evaluate a local variable under debugger and all you get is this:
"Cannot obtain value of local or argument 'whatever' as it is not available at this instruction pointer, possibly because it has been optimized away'.
Well, it turns out there are two different tricks to solve such problems:
1.
Shawn Burke blogs about How to disable optimizations when debugging Reference Source. In a nutshell, you need to:
2.
Another tip is from our VB IDE Dev Jared Parsons: Disabling JIT optimizations while debugging. Essentially, Jared points to create an .ini file with the same name as the application's .exe:
[.NET Framework Debugging Control] GenerateTrackingInfo=1 AllowOptimize=0
He also points to the MSDN article http://msdn.microsoft.com/en-us/library/9dd8z24x.aspx (Making an Image Easier to Debug).
To be frank, this tip didn't work for me for some reason, but I guess it's still worth mentioning.
Hope this helps!
We're currently designing a new IDE feature named Call Hierarchy. Essentially, it allows you to find places where a given method is called, which is similar to how Find All References currently works. However, unlike Find All References, the Call Hierarchy feature provides more deep understanding and more detailed information about calls.
Invocation
You can invoke the Call Hierarchy toolwindow by right-clicking on a method, property or constructor name in the code editor and choosing View Call Hierarchy from the context menu:
Tool window
A toolwindow will appear docked on the bottom of the Visual Studio window:
You can expand the node for the method to see information about it: incoming calls to the method ("Calls To") and outgoing calls ("Calls From"):
Here's how it works. A method (or a property, or a constructor) is displayed as a root in the treeview. You can expand the node to get a list of "search categories" - things you want to find. Four search categories are currently supported:
When you expand a search node (such as Calls To 'GetCallableMethods'), a solution-wide search is started in the background and the results appear under the Calls To folder. You can click on a result, and the details will appear in the Details list view on the right hand side.
The Details list view shows all the exact call sites and locations in code where GetCallableMethods is called from GenerateXsdForComplexTypes. We see that the method is being called only once, the line of code is shown, as well as file name and position in the file. Double-clicking on that call site will navigate to it in the code editor.
The advantages of Call Hierarchy compared to Find All References is that it allows you to explore and drill deep multiple levels into the call graph (find caller's caller etc.) Also, Call Hierarchy has deeper and more fine-granular understanding of the source code - while Find All References just finds the symbols, Call Hierarchy differentiates abstract and virtual methods, interface implementations, actual calls from delegate creation expressions, etc. Also it works like a scratch-pad: you can add any member as another root-level item in the call hierarchy tool window and have several members displayed there at once. Finally, the Details Pane given information about the concrete call sites, if a method is being called several times in the body of the calling method.
Toolbar
In the toolbar you can select the scope of the search: search in currently opened file only, current project or the entire solution.
Refresh button re-fills the treeview in case the original source code was modified.
If a root node of the treeview is selected, the "Delete Root" button will remove it from the treeview. You can add any member as a new root in the treeview by right-clicking on it in the context menu:
or adding it from the source code as described in the beginning.
Finally, the Toggle Details Pane button shows or hides the details pane.
Some design issues and implementation details
Although the feature is already implemented and if you have the Visual Studio 2010 CTP, you can already play with Call Hierarchy, we're still not quite happy with the current UI design, usability and the user experience.
For example, one issue that we're seeing is that it takes 2 mouseclicks and 2 mousemoves to invoke the Find All References search, but it takes 4 mouseclicks and 4 mousemoves to get the callers list for a given method (1 click - menu invocation, 1 click - menu item selection, 1 click - expand the treeview node for the method, 1 click - expand the "Calls To" folder). Although the search itself will be slightly faster than Find All References, the perceived complexity of invoking the feature is something we definitely want to improve. We want this feature to be at least as good and usable as Find All References, but also provide additional benefits, otherwise people will just not use the feature and continue using Find All References.
I think I'll stop for now and see what kind of feedback you guys might have about this. In the next blog post I plan to share more of our current thinking and what we'd like to change. For now, I'd be really interested to know what you think and if you have any suggestions or ideas. Now it's not too late, and we can change the feature based on your feedback.
I've been monitoring my coding style for quite a while and I noticed that I often prefer chaining method calls to normal control flow. Now I think it might not always be such a good idea.
To give you an example, today I had a task of reflecting over constants in a class and stuffing them into a dictionary. Here's a sample to demonstrate my original approach. In this sample I replaced the actual domain model with a fake colors domain and the task is to implement two methods: FillColors and OutputColors.
using System; using System.Collections.Generic; static class Program { public const string Red = "#FF0000"; public const string Green = "#00FF00"; public const string Blue = "#0000FF"; static void Main(string[] args) { var dictionary = new Dictionary<string, string>(); FillColors(dictionary.Add); OutputColors(dictionary); } static void FillColors(Action<string, string> add) { var fields = typeof(Program).GetFields(); fields.ForEach(f => add(f.Name, f.GetRawConstantValue().ToString())); } static void OutputColors(Dictionary<string, string> dictionary) { dictionary.ForEach(p => Console.WriteLine(p.Key + " = " + p.Value)); } static void ForEach<T>(this IEnumerable<T> list, Action<T> action) { foreach (var item in list) { action(item); } } }
First, several interesting comments about the code.
But I digress. Let's go back to the actual topic of me writing one long line:
fields.ForEach(f => add(f.Name, f.GetRawConstantValue().ToString()));
instead of:
foreach (var f in fields) { add(f.Name, f.GetRawConstantValue().ToString()); }
Here are several observations that favor foreach against ForEach:
ForEach is not in the library
As of .NET 3.5 SP1, ForEach is not in the library so I had to implement it myself. For .NET 4.0 I've logged a suggestion with Mads to add it to the BCL, but I'm not sure if we're adding it for 4.0. A lot of people seem to add it to their libraries so I think it'll be useful to have regardless of the coding style it suggests. I'm sure it is useful at least sometimes.
ForEach hides state mutation
Eric Lippert told me that he's not a great fan of ForEach because it conceals state mutation - it takes an eager (non-lazy) control flow statement that mutates state and hides it behind a functionally-looking call.
You can't put a breakpoint inside ForEach "body"
If you use foreach, you can put a breakpoint on the add call, whereas you can't put a breakpoint on the add call in the first case. This is not a language problem, but rather a tooling issue, but still I don't see tools (yes, debugger, I'm looking at you!) becoming comfortable enough in this scenario anytime soon.
Stack is polluted
In the first case (ForEach), two additional frames are on the stack which looks kinda ugly during debugging:
vs. the original:
This may not have a good impact on the debugging story.
Performance is worse
Although I know that micro-managing performance is a bad thing to do, we still create an anonymous method (metadata bloat) and have two additional calls on the stack (I know that JIT will probably optimize them, but who knows). So the danger is that in critical codepaths (bottlenecks) the performance will degrade compared to using control flow (which the JIT will compile into a couple of nice fast JMP instructions).
Readability suffers
Readability is probably worse because ForEach is not as familiar as foreach. Also, the code lines tend to grow long with the first approach and I like my lines of code less than 80 characters.
ForEach is NOT functional style
I'd like to stress that I'm still a huge fan of functional style, immutability, composability, first-class functions, etc. The ForEach style described in this blog-post is NOT functional style, although it definitely looks like it.
We had a hallway conversation with Chris Smith from F# team about this coding style topic today, and even he (the functional programming guy and a huge F# fan) admitted that sometimes C# should better use C# native constructs instead of borrowing from other (albeit awesome) languages like F#.
Summary
So I guess I'm going back to more using good old control flow statements again as they deserve it. They have been here for 30 years for a good reason and I don't think they're going away anytime soon.
http://twitter.com/KirillOsenkov
Goodbye productivity...
We have announced a list of new IDE features for managed languages in Visual Studio 2010:
http://blogs.msdn.com/somasegar/archive/2008/12/19/code-focused-development-in-vs-2010.aspx
Chris Smith from the F# team has recently posted some "interesting" news:
http://blogs.msdn.com/chrsmith/archive/2008/12/10/f-no-longer-vaporware.aspx
Mike Benkovich from http://benkotips.com and my fellow C# QA team member Eric Maino have talked me into doing a webcast on Visual Studio Tips & Tricks. Mike was the host, and Eric and I were showing VS features that we like and use often in our day-to-day coding.
Here's a list of tips that Eric and I were showing:
http://blogs.msdn.com/benko/archive/2008/12/17/visual-studio-tips-tricks-listing.aspx
And here's the webcast itself:
http://blogs.msdn.com/benko/archive/2008/12/15/benkotips-webcast-9.aspx
Hope you like it!
At my job on the C# IDE QA team I've learned some useful things about debugging in Visual Studio, which I'd like to summarize in this post. Although the screenshots were made using Visual Studio 2008 SP1, this pretty much applies to other versions of VS as well.
Rich debugging support
When you develop your C# application and hit F5, the target process (your program) gets started, and then the Visual Studio process attaches the debugger to the process where your code is running. This way, you can break into the debugger and VS will provide you with all sorts of rich debugging support - current statement highlighting, call stack, watches, locals, immediate window, Edit-and-Continue and so on.
More importantly, if your application throws an exception or crashes, the debugger will intercept that and provide your with all the information about the exception.
As a side note, in Visual Studio there is a way to run your code without attaching the debugger - the shortcut is Ctrl+F5. Try throwing an exception in your code when using F5 and Ctrl+F5 to feel the difference.
throw null;
By the way, my favorite way to artificially throw exceptions is throw null; I just love the fact that it throws a NullReferenceException because it can't find the exception object and nevertheless does exactly what I want it to do :)
Crashes and the Watson dialog
What if a program crashes or throws an exception, which you don't have source code for? Moreover, you didn't start the program using F5, but the operating system launched the process. I remember that before coming to Microsoft, the only thing I could do about some application crashing was to express my disappointment about the fact (usually in Russian). Now I don't feel helpless anymore, because I've learned a couple of tricks. As an example for this we'll crash Visual Studio itself and then debug the crash.
How to crash Visual Studio?
Viacheslav Ivanov reported an interesting crashing bug in our language service recently. Save all your work and then paste this code in a C# Console Application and change 'object' to 'int':
using System; static class Program { static void Main() { ITest<object> test; test.Test((object /* and now change the argument type to "int" */ i) => { }); } } public interface ITest<T> { } public static class Extensions { public static void Test<T, I>(this ITest<T> test, Action<ITest<I>> action) { } }
What you will see is the Watson dialog:
Given this chance, I'd highly recommend everyone to click "Send Error Report" if you ever see this dialog for Visual Studio. Many people "Don't Send" and frankly I don't understand why not. There is no personal information being sent, and we don't want your personal information anyway, honest. What we want is a call-stack and minidump, if possible, so if you want us to fix the product to make it more stable in the future, you will greatly help us if you send us the Error Report. By the way, we usually fix most (if not all) crashes that come in through this dialog, so the chances that we'll fix the crash you report using the dialog are actually pretty high. For example, we've already fixed the bug mentioned above and it works just fine in current builds.
Attaching a debugger
So what can you do if an application crashes or hangs? You can attach the debugger to a running process, even if it has already crashed. The code is still being executed (the main thread of the crashed application is usually pumping messages for the error dialog). You can either choose "Debug" on the Watson dialog, or (what I usually do) is start a new instance of Visual Studio myself and attach to the process manually, without dismissing the Watson dialog.
Note: if the debuggee process crashes and you attach the debugger after the fact, you'll have to manually break into the debugger by pushing the "Pause" button. If the debugger was already attached at the moment of the crash, then it will offer you to break or continue.
You can attach the Visual Studio debugger to a running process by choosing Tools | Attach To Process (Ctrl+Alt+P):
You will see the Attach to process dialog:
Interesting things to note here are the Attach to: selection. Since Visual Studio is a mixed-mode managed/native application, to get call stacks for both managed and native parts, you'd want to attach to both of them (by clicking Select...):
If you select both Managed and Native, you'll get richer debugging information about your callstacks - this is recommended.
Note: if you want to enable mixed-mode debugging (managed+native) for the application that you have source code for, go to project properties of the startup project, and on the Debug tag select "Enable unmanaged code debugging". Then the debugger will automatically attach using mixed-mode.
Finally, select the process from the list which you'd like to attach to (in our example, it will be devenv.exe) and click Attach. Notice that the process of the debugger itself is not shown in the list, that's why you don't see two devenv.exe in the list.
Remote Debugging
What many people don't know is that VS can be used to debug a process running on another machine on the network. To do this, you just need to start the Visual Studio Remote Debugging Monitor on the same machine with the process you want to debug:
The remote debugging monitor will listen to debugger connections on the other machine and you'll be able to attach the debugger using the Transport and Qualifier fields on the Attach to process dialog:
You can find more detailed information about Remote Debugging in MSDN and on the internet.
Set Enable Just My Code to false
One very important option in Visual Studio is "Enable Just My Code", which is set to true by default. To be able to see more information on the callstacks instead of just "Non-user code", you need to go to Tools | Options and disable this option:
I usually do this right after I install Visual Studio, so that I can always debug into "not my code".
Other interesting options on this page are:
Break on first chance exceptions
One very useful option in the debugger is the ability to break whenever a first-chance exception is being thrown. A first-chance exception is an exception that might be caught by the program itself later in some surrounding catch block. First-chance exceptions are usually non-fatal and handled (or swallowed) by the user, so they might not even be visible to the end user during normal execution. However, if a first-chance exception is not handled in the code and bubbles up to the CLR/OS, then it becomes a crash.
So, to break on first-chance exceptions, you can go to Debug | Exceptions to invoke the Exceptions dialog:
Here you can put a checkmark on Common Language Runtime Exceptions for the debugger to break every time a managed exception is thrown. This way you will see more hidden exceptions, some of them originating deep in the .NET framework class library. Sometimes there are so much first-chance exceptions that you can become overwhelmed, but they are incredibly useful to get to the root cause of the problem, because the debugger will show exactly where the exception originated preserving the original surrounding context. Another great advantage of breaking on first-chance exceptions is that the call stack is not unwound yet and the problem frame is still on the stack.
Debugging tool windows
OK, so now that we know how to attach a debugger and how to set the debugger options, let's see what happens after we've attached a debugger. For our exercise, you can open two instances of Visual Studio, attach the second instance's debugger to the first one, and then crash the first one using the lambda-expression crash code above. Instead of the Watson dialog on the debuggee process, you will see the following window in the debugger:
Now you have the chance to break and see where the exception happened. Continue is useful if the exception is actually a first-chance exception and you'd like to pass it on to user code to handle it. Let's hit Break and examine what tool windows are available under debugger.
Processes window
All the debugger windows are available from menu Debug | Windows. The Processes window shows the list of processes that the debugger is currently attached to. A nice trick is that you can actually attach to multiple processes at the same time. Then you can use this window to switch the "current" debuggee process and all other tool windows will update to show the content of the "current" process.
Note: on our team, we use this window a lot, because our tests run out-of-process. Our test process starts Visual Studio in a separate process and automates it using DTE, remoting and other technologies. Once there is a failure in the test, it's useful to attach to both the test process and the Visual Studio process under test. The most fun part is when I was debugging a crash in the debugger, and attached the debugger to the debugger process that is attached to some other process. Now if the debugger debugger crashes on you on the same bug, then you're in trouble ;) Sometimes I definitely should blog more about the fun debugging stories from my day-to-day job. But I digress.
Threads
As we all know, processes have multiple threads. If you break into a debuggee process, you will most likely end up with a list of threads that were active at the moment when you did break. Main thread is the green one - this is the UI thread of your application (in our example, Visual Studio). Main thread executes the application message loop, and is pumping the windows messages for the application's UI. If a message box or a dialog is shown, you will see this dialog's message loop on the main thread.
To switch threads, double-click the thread name that you're interested in. In most of the cases you'll be interested in the main thread. But if you start your own threads, give them a name so that they are easy to find in the threads list.
Call stack
Every thread has a call stack. Call stack is probably the most important thing you'd like to know about a crash - what was the sequence of function calls that lead to a crash? If the program is hanging, you'd like to know what function is it hanging in and how did it get there. Oftentimes by just glancing at a callstack you immediately know what's going on. "Is this callstack familiar?" or "Who is on the callstack?" is probably the question we ask most often during the bug triage process.
Anyway, here's the call stack window:
In our example we see that the C# language service module is on the stack (.dlls and .exes are called "modules" in the debugging world).
However instead of function names from cslangsvc.dll we see the addresses of the procedures in memory. This is because the symbols for the cslangsvc.dll module are not loaded. We'll look into how to load symbols in a moment.
Modules
The Modules window shows a list of .dlls and .exes loaded into the debuggee process:
There are multiple ways to load symbols for a given module. You can right-click on a module for a list of options:
Symbols for modules are stored in .pdb files and are produced with every debug build of the binary. pdb files contain mapping from compiled binaries back to the original source code, so that the debugger can display rich information (function names, source code locations, etc.) for the binary being debugged. Without symbols, debugging is only possible at the assembly level and registers window, you can't map the binaries back to the source code.
Symbols
A very useful dialog is the Tools | Options | Debugging | Symbols:
Here you can set paths where to look for the .pdb files. Normally, the .pdb files will be directly next to the binaries, in which case they are usually found and loaded automatically. Loading symbols takes some time, so Visual Studio supports caching symbol files to some directory. Also, if you don't want all the symbols for all the binaries loaded (it can take a while), you can check the checkbox "Search the above locations only when symbols are loaded manually". Load symbols from Microsoft symbol servers provides symbols for Microsoft products, such as Windows and Visual Studio. You can load symbols from here, or also from the Modules or Call Stack windows, by right-clicking on a module and choosing Load Symbols From. Since we're debugging into Visual Studio, the symbols are located on the Microsoft Symbols servers:
When we load public symbols, the following little dialog is showing:
After we've loaded the symbols for cslangsvc.dll we notice that the Call Stack window is now much more informative:
Given this call stack, anyone of our developers will now easily be able to pinpoint the problem. In our example we see that the problem happens when we try to show the Smart Tag for the Generate Method refactoring:
As you see, there are more modules for which the symbols haven't been loaded yet. You can load the symbols for those modules by right-clicking their stack frame and choosing Load Symbols From. Loading all the symbols is usually recommended for more detailed information.
That is why the call stack is so precious during bug reports. To save the call stack, you can Ctrl+A and Ctrl+C to copy all the stack into the clipboard. When you click Send Error Report in the Watson dialog, the call stack is included in the error report.
Also you see that the call stack is not very useful without the symbols - it's the symbols + the callstack that provide rich information about the crash.
Minidump
Another very useful information that you can provide about the crashed process is the memory dump (heap dump, minidump) - this is basically a snapshot of the memory state of the crashed process. To create a minidump, go to Debug | Save Dump As. Visual Studio will offer you to save the dump to a location on disk, and an option to just save the Minidump or Minidump with Heap:
Minidump with Heap will save more information than just the minidump, but will take a whole lot more disk space (for Visual Studio - possibly hundreds of megabytes - depending on the process working set size during the crash).
Those are the three components that we usually send to our developers during crash bug reporting:
In most cases, they are able to understand the problem given this information. A list of repro steps is usually even better, because they can reproduce the problem themselves and enable first-chance exceptions to break early into the problem area.
Debugging hangs
If an application hangs, you can attach the debugger to it and hit break to see what thread and what call stack blocks execution. Usually looking at the call stack can give you some clues as to what is hanging the application. Debugging hangs is no different than debugging crashes.
Microsoft shares customer pain
Finally, I'd recommend everyone to watch this video:
Conclusion
In this post, I've talked about some things worth knowing for effective debugging sessions:
Do let me know if you have feedback or corrections about this information.
I wanted to sum the total lines of code in files in a given folder. I thought that writing my own program to do this would be faster than looking for it on the internet, so here's what I came up with (1 line broken into 7 lines to fit into your blog reader):
using System; using System.Linq; using System.IO; class Program { static void Main(string[] args) { Console.WriteLine( Directory.GetFiles( Environment.CurrentDirectory, "*", string.Join(" ", args).Contains("/s") ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly) .Select(f => File.ReadAllLines(f).Length) .Sum()); } }
Just name the executable loc.exe and put it into your PATH - you're good to go. Input "loc" in the command prompt to get the total number of LOC in the current directory, and "loc /s" to do recursive search.
Please note that the way I wrote this program is not very good for debugging, because you can't put a breakpoint on substatements (technically speaking, this program consists of only one statement). In production code, I would rather write something like this:
string path = Environment.CurrentDirectory; string pattern = "*"; string commandLine = string.Join(" ", args); SearchOption searchRecursively = commandLine.Contains("/s") ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly; string[] files = Directory.GetFiles(path, pattern, searchRecursively); IEnumerable<int> lengths = files.Select(f => File.ReadAllLines(f).Length); int totalLOC = lengths.Sum(); Console.WriteLine(totalLOC);
because it better conveys the step-by-step actions and allows to put a breakpoint on any step. However, for my little program, my sense of style guided me to use the former notation.
As another side note, the "production version" doesn't use var for type inference. I think it improves readability in this case.
A while ago we announced Visual Studio 2010 and C# 4.0. In case you'd like to catch up and read articles or watch videos about the upcoming new features, I wanted to gather some links here.
As you probably know by now, C# 4 is mostly oriented on interoperability: better COM interop, better interop with dynamic languages (like Python), better interop with the browser (Silverlight, JavaScript) and better Office interop. Briefly, the new language features are:
What to read about C# 4 language features? Well, first and foremost, there is always Charlie's blog that accumulates all C# news:
C# compiler developer's blogs are a terrific technical resource - highly recommended:
As far as I can tell, we don't yet have a comprehensive resource about the new features in the C# IDE. Well, let me spill the beans and briefly mention them here, before I dive into the details in my upcoming posts.
Justin van Patten has a great overview of upcoming new features in .NET 4.0. It is worth mentioning, that 4.0 will have a new CLR version 4.0 (2.0, 3.0 and 3.5 were all working on the CLR version 2.0). Most notably, .NET will introduce tuples, code contracts, parallel extensions, variance annotations and a whole lot more.
Of course, I'm only scratching the surface of what the next Visual Studio will bring - many teams across the division worked hard and implemented a lot of cool stuff (e.g. Architecture Explorer, Sequence Diagrams, etc). I'm only mentioning some features that I personally find really interesting as a member of the C# team.
In my next blog posts, I will start talking more about the upcoming new features (especially the Call Hierarchy one - since I was the one who tested it).
Static analysis tools allow us to measure code quality and better understand the design and architecture of software. There are things about source code that are not visible to eye in our day-to-day work: dependencies between components, cyclomatic complexity of methods, hidden and indirect dependencies. There are dangers that a method or a type will become overly complex and induce maintenance nightmare without us even noticing it.
Today’s post is about NDepend, a static analysis tool developed by Patrick Smacchia. NDepend measures software quality by extracting metrics, gathering and reporting statistics and visualizing architecture.
Here’s what NDepend does:
Since both Patrick and I like static analysis and are interested in measuring software quality, Patrick suggested that I try out NDepend on one of my projects and share my experiences – and I gladly agreed. I’ve heard about NDepend long ago, and even before I joined Microsoft I blogged about static analysis tools and publicly promised to take a look at NDepend someday, which I felt was a very interesting tool with unique capabilities. Well, since Patrick recently contacted me himself :), there can be no better opportunity to download NDepend and give it a try. Here I’ll provide my first impressions.
I went to www.ndepend.com and started to look around. I liked the site and the fact that there were screenshots and some nice 3-min overview videos. Seconds after clicking on a big download button, NDepend was on my desktop. It comes with two executables – command line NDepend.Console.exe (for the build automation) and the UI VisualNDepend.exe. Of course, I started the VisualNDepend first and it presented me with a nice start page:
The next thing is to create a new NDepend project and add the assemblies to it that you want to analyze.
After the analysis ran, it displayed a very comprehensive report about my project. Even glancing over this report already provided a lot of useful information to me:
After examining the report, I came back to the main application to find that it presents all the information contained in the report, but interactive:
I have to say that the UI looks great, but at first seems rather overwhelming and I felt like sitting in a Boeing cockpit. But hey – you can’t expect a complex static analysis tool to have a notepad-like interface – it has to expose its features somehow. Surprisingly, you get used to the UI really quickly and I found my way around really easily.
All you have are the following things:
Hopefully this can provide a basic overview of NDepend, what it’s for and what it does, as well as its main features. I was very impressed with the tool, really liked it and looking forward to use it more for better architectural insights and better code quality.
Sometimes I'm being asked what book I'd recommend for learning C#. Until recently, I was hesitant and didn't know what to answer. It depends, among other things, on the following factors:
Well, now I have a good answer for the majority of the cases. Mark Michaelis, a C# MVP, wrote a great book called Essential C# 3.0. It requires pretty much no programming background, and beginners can ramp up easily. One immediate thing about Essential C# 3.0 is that the book is very easy to read. You literally swallow page after page freely and effortlessly. This is one of the major reasons why I'm recommending this book to beginners who ask me where to start.
The first several chapters introduce basic programming concepts - variables, statements, control flow, methods, and continue gracefully to the .NET type system, classes and objects. It's nice to know that even when you're learning the basics, you're learning the latest version of a modern language and an industry standard.
The book continues to do a great job at the intermediate level, with chapters about classes, inheritance, interfaces and value types. A great asset is a special chapter called Well-Formed Types, which collects a series of useful information and best practices, such as overriding object members, referencing other assemblies, generating XML comments, finalization and garbage collection etc.
C# 2.0 features are covered well in a dedicated chapter about Generics and also in other parts of the book (iterators and yield return, anonymous methods).
Of course, given the book's title, C# 3.0 features and LINQ are introduced and explained well in the following chapters: Delegates and Lambda Expressions, Collection Interfaces with Standard Query Operators, Query Expressions. Several other chapters show more aspects of using the C# language: Events, Exception Handling, Building Custom Collections.
Finally, an advanced C# user will find a lot of interesting things here as well. I was particularly attracted by a great chapter on Reflection and Attributes, and the two "icing-on-the-cake" chapters: Multithreading and Multithreading patterns. I've learned a lot of new things for myself here. Also, throughout the rest of the book, special "Advanced Topic" fragments provide a lot of value to an experienced reader. For example, I've learned that the new operator generates newobj IL instruction for reference types and initobj for value types - I didn't think about this distinction before.
To sum up, a great book about C# for every reader - beginner, intermediate, advanced. It's not only about the language - CLR is also covered pretty well (IL, garbage collection, JIT, AppDomains, reflection, threading). This book doesn't cover any of the applied libraries (such as ASP.NET, ADO.NET, WPF or Silverlight), but even without it, it's already more than 700 pages thick. I also really love the formatting, fonts, spacing and illustrations - very ".NET-style".
A great read and highly recommended.
Finally I had time again to continue working on my Live Geometry project on CodePlex. While I was busy with other stuff, Silverlight 2 has officially released and the rest of the world has already upgraded from Beta 2 to the release version. Now I'm catching up: I've updated the source code for both Silverlight (online) and WPF (desktop) editions, so it should build fine. As usual, you can preview the Silverlight (online) edition at:
http://geometry.osenkov.com
As you can see, I started implementing the coordinate grid and axes. I'm thinking to implement pan/zoom functionality by dragging the coordinate system and using the mouse wheel. Also I need to have a toggle button to show/hide the grid/axes, and numbers (-2, -1, 0, 1, 2, ...) to show up along the coordinate axes. Then I can start working on plotting function graphs and charts.
I've also updated the desktop (WPF) version, although I didn't have time to make it look beautiful:
The beauty of WPF is composability. The toolbar icons use the same logic for drawing points/lines/circles as the main canvas. This way the icons are vector graphics and can be scaled if I want to make the toolbar buttons larger in the future. Also, the buttons in the toolbar are generated automatically using Reflection and data-binding, so when I add a class for a new tool, I don't need to do anything else - reflection will pick it up and create a toolbar button for it using WPF databinding.
Also the good news is that the WPF edition shares the same source code with the Silverlight version. Only at two or three places in code I had to use the #if SILVERLIGHT compiler directives, mostly because WPF VisualTreeHelper.HitTest is called VisualTreeHelper.FindElementsInHostCoordinates in Silverlight (because of slightly different semantics). Andy Beaulieu blogs about this breaking change here: http://www.andybeaulieu.com/Default.aspx?tabid=67&EntryID=95
I decided to compile a small list of Visual Studio features that I use a lot.
Code Editor
Navigation
Refactoring
Code generation
Debugging
Solution Explorer
Macros and automation:
P.S. Sara Ford has much much more in her famous Did you know series.
There is a nice game called Enlight from FeejoSoft. I have it on my PocketPC phone and for the life of me I just couldn't get past level 33. So yesterday I finally sat down and implemented an algorithm to solve this game automatically.
Of course, I used C# and Visual Studio (as a tester, I used our latest internal build of Visual Studio 2010, although it will run just as fine on 2008 as well).
The game
The rules are really simple. There is a boolean matrix 10x10, and you can invert cells. When you invert a cell, all its neighbors (usually four) are inverted with it. Given this operation, you are required to nullify the matrix (turn off all the lights):
The game is freeware and you can use your favorite search engine to find and download it (e.g. from freewareppc.com, no responsibility for links). If you'd like to run it in an emulator, here are the steps:
The algorithm
The idea I used is commonly used for such problems (e.g. eight queens puzzle (http://en.wikipedia.org/wiki/8_queens) is usually solved using depth-first search with backtracking). I encourage you to visit this wikipedia article, it is very interesting read.
We'll visit every cell column by column. Every cell will have it's next cell which is down in the next row, or the first cell of the next column to the right. For brute force, you would recurse to visit the next cell, then come back, toggle the cell and recurse again. This way every cell will be tried in both combinations. However this will yield 2^100 iterations. We can considerably trim down the search if we don't recurse for knowingly invalid boards. This way we prune the "phase space" of the problem significantly. Here's the complete code for the solver:
namespace MatrixGame { public class Solver { private Field sourceField; private Field solution = new Field(); private Field currentSolution = new Field(); private Solver(Field field) { this.sourceField = new Field(field); } public static Field FindSolution(Field field) { Solver solver = new Solver(field); solver.Search(FieldCoordinates.StartingPoint); return solver.solution; } private int steps = 0; /// <summary> /// Main algorithm /// </summary> void Search(FieldCoordinates current) { steps++; // we traverse the cells column by column, // left to right, top to bottom var next = current.GetNextCell(sourceField); // we've reached the end of the field if (next.Column == sourceField.Width) { if (LeftCellIsEmpty(current)) { CheckSolutionCandidate(); } return; } // pruning - only continue searching if this is a plausible board so far if (current.Column == 0 || LeftCellIsEmpty(current)) { Search(next); } // let's invert the current cell and search again currentSolution.InvertCell(current); sourceField.Invert5Cross(current); if (current.Column == 0 || LeftCellIsEmpty(current)) { Search(next); } } /// <summary> /// If the cell to the left from current is not empty, /// the current board cannot be a solution - /// no point to continue down this branch. /// Prune this and backtrack to another branch. /// </summary> bool LeftCellIsEmpty(FieldCoordinates current) { return !sourceField[current.Row, current.Column - 1]; } /// <summary> /// We've traversed all elements - /// let's check if what we've come up with is actually a solution /// we checked almost all cells in LeftCellIsEmpty /// let's just check the last (rightmost) column /// </summary> void CheckSolutionCandidate() { if (sourceField.GetColumn(sourceField.Width - 1).IsNull()) { SolutionFound(); } } /// <summary> /// We got it! Do something with the solution! /// </summary> void SolutionFound() { solution = new Field(currentSolution); } } }
The solution program
Here's what I came up with. On the left board, you set up the level like you see in the game (the picture shows The Notorious Level 33!). Left-click to toggle a cell, drag the mouse to "draw" adjacent cells.
On the right, you have a chance to play this level, however, the orange dots show which cells you need to click to turn off the lights. If you feel honest, you can turn off the orange dots using the checkbox.
You can download the full source code here:
http://code.msdn.microsoft.com/EnlightGameSolver
The research
First of all, I was amazed how efficient the pruning is. The fact that we don't check for knowingly invalid boards brings us down from 2^100 to just 93183 times the Search method is executed. On my machine this is so fast, that I manage to recalculate the hint solution in real time, as the user clicks in the left board.
Also, building this project raised more questions than it answered. I'm sure there is a whole science behind this seemingly simple domain - Conway's Game of Life is just around the corner, not to mention MineSweeper, cellular automata, even-odd-logic, 0,1-matrices, constraint programming, etc. etc. It is fascinating how complex solutions exist to invert a single pixel on the board:
What is the pattern here? Is the solution always unique? Why is there no solution for some configurations? What if you apply the solution to the solution? What about unlimited two-dimensional plane? Which single-cell source board have a solution? Which don't? What is special about a board consisting of such cells? What is the ratio of yellow cells for such boards? All these are interesting questions I'd love to think about, if only someone would do my main job for me :)
The challenge
As usual, better/faster/shorter solutions are welcome. I'd be especially curious to see a solution in F# or Prolog. Feel free to reuse my UI code.
We all know that generics are good - they promote code reuse, static type checking by the compiler, increase runtime performance, allow more flexible OOP designs, lay the foundation for LINQ, help the IDE to provide more helpful IntelliSense and have tons and tons of other vital advantages. "var" is another good feature, which (unlike "object"), also helps to preserve full static type information.
However I hit a rare case recently where I had too much static type information about my code, so I had to use System.Object (and boxing) to get the desired effect. I had a method that used reflection to set a property on a type, similar to this:
static void SetProperty(object f) { Type type = f.GetType(); PropertyInfo property = type.GetProperty("Bar"); property.SetValue(f, 1, new object[0]); }
I also had a struct like this:
struct Foo { public int Bar { get; set; } }
Now, I tried to set the Bar property on an instance of the struct:
static void Main(string[] args) { var f = new Foo(); SetProperty(f); Foo foo = (Foo)f; Console.WriteLine(foo.Bar); }
It didn't work! It printed out 0! I was puzzled. And then I realized what is happening. Since Foo is a struct, and f (thanks to var!) is also statically known to be a struct, the compiler passes a copy of the struct by value to the SetProperty method. This copy is modified, but the original f is not.
One simple change and it started working fine:
static void Main(string[] args) { object f = new Foo(); SetProperty(f); Foo foo = (Foo)f; Console.WriteLine(foo.Bar); }
I changed var to object, the struct was boxed into an object on the heap, the reference to this same object was passed to the SetProperty method, method set the property on the boxed instance, and (Foo) unboxed the same modified instance - the code now prints out 1 and everything is OK again.
"var" provided too much type information to the compiler - it avoided boxing, and knew that the variable is a struct, so I lost the modified value. After casting to object, we hid the extra information from the compiler and got the uniform behavior for both value types and reference types.
In my original code where I encountered this peculiar behavior (a custom deserializer that reads XML and uses reflection to set properties on objects), I was too focused on working with all types so I forgot that those can be value types as well. Since I had everything strongly typed with generics, type inference, vars and other modern goodness, the kind hardworking compiler preserved all the information for me and avoided boxing where I was expecting to get reference type behavior. Thankfully, unit-tests revealed the error 10 minutes after it was introduced (I definitely need to post about the usefulness of unit-tests and TDD in the future), so it was a quick fix to box a type into object before filling its properties.
It was an amusing experience.