Thursday, February 26, 2009

DeepZoom Your Code Quality With NDepend

I've recently started playing with NDepend again.  This tool is a sort of data mining utility for your code.  Feed it your assemblies and it can tell you almost anything about them.  Using a custom query language with a SQL-like syntax, you can dig into all sorts of metrics and useful information. Out of the box, it ships with tons of useful queries for common code problems. 

I ran some of our code through it and got dinged on some of the code complexity queries:

 image

In this case, I had several huge methods that needed to be broken up and optimized.  Thanks to NDepend's prodding, I spent some time refactoring using ReSharper, and whittled those down to 0s:

image

That's helpful, but not nearly everything that NDepend can do.  For example, the code I'm testing with is involved in some multithreading, so with a little digging through the docs, I came up with this query to show all methods that change state (besides property and event setters), but don't use any locks:

WARN IF Count < 0 IN SELECT METHODS WHERE
!IsDirectlyUsing "System.Threading.Monitor" AND ( ChangesObjectState OR ChangesTypeState ) AND
!IsConstructor AND !IsClassConstructor AND !IsPropertySetter AND !IsEventAdder AND !IsEventRemover

This doesn't guarantee thread-safe code, but it definitely helps drill down to potential problem areas.

Another area I can see us using this in is to provide metrics for our customers.  Generally they are not concerned with things like Cyclomatic Complexity, but some simple numbers may be useful.  We use FinalBuilder, so it's possible we could run NDepend's console utility to roll the numbers into some XML and publish to their customer wiki.  For example, here's a quick query to spit out the total number of tests for a project:

SELECT METHODS FROM ASSEMBLIES "TestAssemblyName" WHERE HasAttribute "NUnit.Framework.TestAttribute"

Once we get a customer set up with these metrics, we'll post more about how to automate that.  Until then, go check out NDepend!

Wednesday, February 25, 2009

RadEditor for Usable SharePoint Wikis

SharePoint is a great product, but one area where it really lacks is in it's Rich Text Editor.  It doesn't work in anything but IE, and doesn't include an image upload feature.  With a little digging, I found this free replacement from Telerik:

http://www.telerik.com/community/free-products.aspx (ASP.NET RadEditor for MOSS Lite)

Installation is non-obvious in the normal sharepoint way:

  • Run stsadmin.exe to install a wsp
  • Deploy in central admin
  • Turn on in site settings -> site features
  • Restart IIS.

It comes with a chm help document (which if you’re using vista you’ll need to unblock to view) that outlines the steps.  To turn on for a Wiki, follow the steps in ‘Using RadEditor in List Items’, and you'll have a much more usable SharePoint Wiki!

Test Your Web App in Any Browser

http://www.xenocode.com/browsers/

This is a cool free offering from application virtualization company xenocode.  Just choose the browser and version and run.  The single standalone exe "just works" with no install, and allows you to run different versions of IE side-by-side. The browser has localhost access, meaning you can test development web apps running on your machine.  We'll definitely be using this and looking into xenocode more...

Tuesday, February 17, 2009

Quiet For A While

imageThe other day, I noticed several missed calls.  Once again, I'd left my phone on 'meeting mode' all day.  Then it struck me - usually when I turn off my ringer, I know how long I want to turn it off for.  I'm in a meeting, at a movie, out to eat, at church, or somewhere else where I can reasonably guess how long I'll want my phone off. So I threw together my first Windows Mobile app in a while- QuietForAWhile.   Run, and it gives you a handful of finger-friendly buttons for choosing how long to stay on vibrate.  After the elapsed time, it turns the ringer back on.

This is definitely beta stuff, but feel free to try it out and let me know if you have any suggestions!  On my list already:

-Assign to default "meeting mode" button. 
   -Make the UI less 1989.

Download Quiet For A While

Monday, February 16, 2009

Improve .NET Web Client Performance by Increasing MaxConnections

I've spent the last few days deep in .NET tuning trying to squeeze some extra performance out of a relatively simple loop of webservice calls.  I wrote integration tests to time various numbers of worker threads making various numbers of web service calls.  I quickly discovered a few interesting points.

Above 5 or so worker threads (on my dual core laptop), the overall time to execute all webservice calls goes up or does not improve.  This underscores the fact that a computer can only do so much work.  Multithreading gives the appearance of doing work simultaneously, and on multi-cpu machines actually does do work simultaneously, but spinning up a new thread for every activity is generally a bad idea. Each thread has some overhead in terms of memory and processor usage, so using too many can be worse than not using enough. Use the ThreadPool.QueueUserWorkItem or Async methods (which in turn use the ThreadPool) for common threading tasks.

Even with the above practice, it looked like there were still some bottlenecks.  A post on to StackOverflow led me to look at 'maxConnections'.  Apparently, as .NET pools TCP connections, they deliberately limit apps to 2 active connections (I assume per process) .  Microsoft recommends setting this to 12 times the number of CPUs.  I set it to 24 and instantly doubled the speed of my tests.  Setting it higher did not improve things.

<system.net>
  <connectionManagement>
    <add address = "*" maxconnection = "24" />
  </connectionManagement>
</system.net>

That's pretty impressive bump for 5 lines of configuration.  They offer up some additional configuration adjustments to tune your app or server, but these did not apply in my scenario (ie, not in ASP.NET).

Friday, February 13, 2009

3 Years Later, Why Hasn't WS-* Caught On?

This is probably more of a rant, but this article about WS-Discovery in WCF 4.0 got me thinking about an issue I've seen several times lately.  I'm a big fan of WCF - I like being able to drop in various features, etc. fairly easily with a few config changes (however terse they may be).  But without fail, anytime I need to interop with non-.NET systems, they can't consume anything but "old" SOAP 1.1.  No biggie for me - I just create an endpoint with basicHttpBinding, but there are some downsides.  To secure the traffic, I have to register SSL and don't get the 'Secure By Default' features of wsHttpBinding.

A quick google search shows some effort at least in the Java world to support WS*, but I've yet to run into a non-.NET shop that uses this.  For all practical purposes, the only framework using WS-* standards is still .NET.  But if you're consuming your own services, you're probably in the same network, which means netTcp is the route to go.  The only exception being if you had a remote .NET WinForms/WPF client that needed to talk over the internet to a service back home, but even then if you're doing Silverlight, wsHttp is not an option.  Which means WCF's WS support is about as useful as if it supported Esparanto.

All this isn't to say WCF _shouldn't_ support WS-*, rather some jolt is needed to get more widespread adoption of the standards.  I'm not really sure what the answer there is.  This is tricky stuff - adoption tends to go at the pace of the slowest adopter.  That said, other technologies such as REST and AtomPub seem to have better adoption, despite being relative newcomers. 

Tuesday, February 10, 2009

7 Ways to Be a Better Programmer in 6 Minutes

Title says “8”, but I’m not sure “write your own compiler” is either 6 minutes or a way to be a better programmer. The others are good, though:

http://www.secretgeek.net/6min_program.asp

To make up for #8, I'd add:  Get resharper.  It's like having FxCop running continuously in the background, plus a helper to intelligently fix problem code.

Monday, February 9, 2009

Microsoft Usability Enrollment Form

A huge, ugly form with tiny fonts and too many options. Sigh.  I love you Redmond, but seriously you get on my nerves sometimes.

image

http://www.microsoft.com/usability/enroll.mspx

Friday, February 6, 2009

jQuery: Use Convention Over Configuration to Make Your Pages Smart

If you're not familiar with jQuery, it is a JavaScript library that lets you quickly access page elements using CSS-like selectors, and then do common effects, animations, and transformations against those elements.  It nicely brushes away browser-compatibility issues and gives you a clean, simple way to do client-side "stuff". 

It ships in ASP.NET MVC, so I've been using it in one of our first MVC apps, and love it.  What I particularly like, though, is using it to develop 'convention over configuration' for the app's client-side behavior.  Instead of wiring up each individual form element, button, etc., I can declaratively say 'all elements with this class should behave this way.'  This is done once in my site.master, so that in the actual pages, applying a behavior is as easy as including a css class name on an element.

Let's look at some examples.  The first step in most jQuery code is to wire up the document ready function.  This tells the browser to execute some function whenever the document finishes loading, which believe it or not is quite difficult to do in a cross-browser way that plays well with other scripts.  To do this, I have a script in my site.master's <head> section that looks like this:

<script type="text/javascript">
        $(document).ready(function() {
            //TODO: set up conventions
        });
</script>

The dollar is how you select page elements in jQuery.  $(document) says "get the current document" (also non-trivial in un-aided javascript).  You can also use css-like selectors.  For example $("#myButton") will return all elements with the id "myButton".  $(".initialFocus") will return all elements with the class "initialFocus".  Which leads to my first "convention":

$(".initialfocus").focus();

Now, in any page that uses the master page, if a particular field should get focus when the page loads, simply specify the class "initialFocus":

<input type="text" class="initialfocus" name="somefield"/>

Or, in MVC parlance:

Html.TextBox("QuantityDelivered", currentTransaction.QuantityDelivered, new { @class = "initialfocus" })

Which is a nice UI touch, but let's look at something more advanced.  I also want a convention to let me specify that a field can be populated using a pop-up date chooser.  For this, I download the jQuery UI framework, and set up the convention:

$(".shortdate").datepicker();

Similarly, I add 'shortdate' as a class to any textbox, and the date chooser appears on the element.  If I decide I want to change some behavior site-wide, I have one simple place to change it.  For example, I could use one of the dozen other jQuery date pickers, or roll my own.

It's also possible to 'stack' effects.  For example, this application displays informative message as a div with the class name "messageBox".  If one of these appears when the page first loads, it hides after a few seconds.  To accomplish this, you simply 'stack' an "animate" (which in this case is just used as a 5 second delay), followed by a fadeOut:

$(".messagebox")
    .animate({ opacity: 1.0 }, 5000)
    .fadeOut("slow"); 

All told, this particular app currently has 6 'conventions', with more planned:

$(document).ready(function() {
         $(".initialfocus").focus();
         $(".shortdate").datepicker();
         $(".longdatetime").datepicker();
         $(".print").click(function() { window.print(); });
         $(".delete").click(function() { return confirm("This record will be deleted.  Are you sure you want to continue? Click 'Ok' to delete this record or 'Cancel' to stay on this page."); });
         $(".messagebox")
             .animate({ opacity: 1.0 }, 5000)
             .fadeOut("slow"); 
     });
So, go get jQuery, whether or not you're using MVC.  With just a few lines, you can really spice up an application's client-side experience.