The StackOverflowException

Take a look at the following code:

class Program
{
    static void Main(string[] args)
    {
        try
        {
            RecurseForever();
        }
        catch (StackOverflowException)
        {
            Console.WriteLine("Caught Stack Overflow Exception");
        }
        catch (Exception)
        {
            Console.WriteLine("Caught general Exception");
        }

        Console.ReadLine();
    }

    static void RecurseForever()
    {
        RecurseForever();
    }
}

What do you think the output of the program will be?

If you had asked me a few days ago I’d have said the output would be “Caught Stack Overflow Exception”, however that isn’t the case. If you run the code in the debugger this is what you actually get:

StackOverflowException

The exception simply isn’t caught.

If the application isn’t being debugged it will simply end at this point. It goes directly to jail. It does not pass GO. It does not collect £200.

ConsoleApplication2 has stopped working

I guess I've never needed to do this before…

I guess I’ve never created a struct in a while (at least in Visual Studio 2008 using C# 3.0) because I’ve just discovered that the Automatic Properties don’t work in structs.

I’ve just created this struct:

public struct CapacityUnit
{
    public string Name { get; private set; }
    public long Multiplier { get; private set; }

    public CapacityUnit(string name, long multiplier)
    {
        Name = name;
        Multiplier = multiplier;
    }
}

Which at first glance looks okay except that I get a compiler error in the constructor on Name. The reason for this is that structs need to have the fields initialised before the this object can be used. Name uses this implicitly as in this.Name. So, it would seem that there is no way, at least as far as I can see, to initialise these properties when using Automatic Properties as I would need to use an implicit this.

Quote of the day

“Just changing your variable name rarely affects the outcome of your code. Just as naming your dog one name vs another. The dog is still the same dog.” [^]

The try-catch-ignore anti-pattern (again!)

I’ve blogged about this a few times, but today I just want to highlight the frustration this causes on fellow developers. Earlier today I saw a tweet from Chris Canal that said:

Are you swallowing exceptions there?! Hold on, let me get something to break your fingers with 😐” [^]

All too often I’ve seen the just-ignore-it school of software development when it comes to error messages. It makes it very difficult to track down bugs.

If there is a valid reason for ignoring an exception then document it. State clearly in the comments exactly why you are ignoring the exception. Log the exception at the very least – I want to know when it happens, how often and why. I don’t like errors being swallowed up. I like to have them all fixed.

Incidentally, when I set up the development wiki in my company one of the first things was to put the quote on the front page “Always write software as if the person that will have to maintain it is an axe wielding maniac” – It is a very good rule to develop software by. I highly recommend it.

It's that time of year again

It seems to be that time of year when lots of students are on forums trying to persuade people to do their homework for them. Since I’ve found difficulty in finding good quality software developers in the past there is no way I’m going to contribute to producing any more debased lazy Muppets claiming to be programmers. The rules of the forums I frequent most often are very simple, and I’d imagine that most forums will have the same set of rules. Basically the person requesting help has to show what they’ve done already then they can expect to get advice on how to fix the problem. If the question comes in and it is just a set of questions with a plea that their homework assignment is due the next day then they are likely to feel the wrath of several professional software developers that have most likely had to clean up the excrement left by previous generations of these inattentive indolent laggards.

I would like to make it perfectly clear for any student that is genuinely struggling with an assignment that forums are an excellent place to seek help. However, you must show that you’ve made an attempt yourself, that you’ve attempted to research the topic and that you are genuinely seeking help and not just a free ride. If you are willing to work through the problem yourself (with some assistance from folks on forums) then you will attain a greater understanding and you are more likely to reach that AHA! moment where everything clicks in to place in your mind. And what a joy that feeling is!

New article on Code Project: Data Visualisation with Virtual Earth ASP.NET Controls

It has taken a while, but I finally got around to putting another article up on Code Project. The article is based on a series of blog posts (Finding things with Virtual Earth, Using PushPins with the Virtual Earth ASP.NET control, and Drawing lines on the map with the Virtual Earth ASP.NET control) that I wrote on the subject on ASP.NET Controls for Virtual Earth. However, it is updated and includes extra information on Polygons that wasn’t in my original blog post series.

You can find the article here: Data Visualisation with Virtual Earth ASP.NET Controls

Formatting dates the hard way

I was doing a bit of a code review and I spotted this in the code base.

string[] splitOptions = new string[1] { dayEarlier.Date.Year.ToString() };
string[] earlyDates = dayEarlier.Date.GetDateTimeFormats();
string[] earlySplit = earlyDates[67].Split(splitOptions,
    StringSplitOptions.RemoveEmptyEntries);
earlySplit[0] = earlySplit[0].Replace(",", string.Empty);

Essentially the code gets the date in a specific format. However, it does it in the oddest most convoluted way I’ve ever seen.  Just to explain, here is the code again but this time I’ve added some comments:

// dayEarlier is a business object with a property called Date that returns a DateTime.
// splitOptions will contain the year in an 1-element string array.
string[] splitOptions = new string[1] { dayEarlier.Date.Year.ToString() };

// earlyDates will contain the dayEarlier Date in umpteen different formats.
string[] earlyDates = dayEarlier.Date.GetDateTimeFormats();

// earlySplit will contain the 68th (!) formatted date (out of 89 that get generated).
// Element 0 in this array will contain the bit upto the year, element 1 will contain
// the bit after the year. The year itself is discarded.
string[] earlySplit = earlyDates[67].Split(splitOptions,
    StringSplitOptions.RemoveEmptyEntries);

// The first element (element 0) of earlySplit is then modified to remove the comma.
earlySplit[0] = earlySplit[0].Replace(",", string.Empty);

In short, what is actually being looked for is the day name, day of the month and the month. That’s it. And that, apparently, isn’t even in the 89 permutations of the date that .NET generated in the second line of code. To add to the potential problems with this, I’ve not seen any documentation that states that the permutations given by this method will stay the same.

All this code could easily be re-written simply as:

dayEarlier.Date.ToString("ddd dd MMM");

And the bonus here is that we are not generating 88 completely useless permutations, nor are we generating the permutation that is simply the closest match that we still have to futz around with. We are generating the date in exactly the format that we want. (Current culture permitting)

Throwing exceptions

When reviewing some code today I noticed some code that catches an exception, does something with it and then explicitly throws it again. The code looked something like this:

try
{
    // Do something that might cause an exception
}
catch (Exception ex)
{
    // Some stuff
    throw ex;
}

The problem with the above code is that when you throw the exception again the details about where the exception originated from are lost because the throw populates that part of the exception object. So the original details are replaced with the details about the current location in the code.

Consider the following program:

static void Main(string[] args)
{
    try
    {
        A();
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
        Console.WriteLine(ex.StackTrace);
    }
    Console.ReadLine();
}

private static void A()
{
    B();
}

private static void B()
{
    try
    {
        C();
    }
    catch (Exception ex)
    {
        // I can do something
        Console.WriteLine("Method C() catches the exception and partly handles it");
        Console.WriteLine();
        throw ex;
    }
}

private static void C()
{
    D();
}

private static void D()
{
    Exception ex = new Exception("This exception is thrown in D");
    throw ex;
}

The original exception is thrown by method D. The code in method B catches the exception and partly handles it, it then explicitly throws the original exception again. When the exception is finally caught in the Main method the call stack is truncated to method B. It can no longer see that method C and D were also called.

The output of the application is:

Method C() catches the exception and partly handles it

This exception is thrown in D
   at ConsoleApplication1.Program.B() in d:DevelopmentConsoleApplication1Cons
oleApplication1Program.cs:line 40
   at ConsoleApplication1.Program.A() in d:DevelopmentConsoleApplication1Cons
oleApplication1Program.cs:line 26
   at ConsoleApplication1.Program.Main(String[] args) in d:DevelopmentConsoleA
pplication1ConsoleApplication1Program.cs:line 14

As you can see, the stack trace only goes from the point of the second throw to the point that the exception is caught.

There are two correct solutions to this problem.

Solution 1: Wrapping the Exception

If you have additional information to add to the exception object you can create a brand new Exception and then put the original exception in as an inner exception like this:

try
{
    // Do something that might cause an exception
}
catch(Exception ex)
{
    // Some stuff
    Exception moreDetailedEx = new Exception("A message with more details", ex);
    throw moreDetailedEx;
}

NOTE: Please use a specific exception class and not Exception this makes catching specific types of exception easier and more efficient as the compiler can put in place some optimisations for you over you catching the base Exception class and examining it. I’m using Exception here simply to make the example easier to read.

So, if we change our program above to create a new exception and wrap the old one in it it will now look like this:

static void Main(string[] args)
{
    try
    {
        A();
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.InnerException.Message);
        Console.WriteLine(ex.InnerException.StackTrace);
        Console.WriteLine();
        Console.WriteLine(ex.Message);
        Console.WriteLine(ex.StackTrace);
    }
    Console.ReadLine();
}

private static void A()
{
    B();
}

private static void B()
{
    try
    {
        C();
    }
    catch (Exception ex)
    {
        // I can do something
        Console.WriteLine("Method C() catches the exception and partly handles it");
        Console.WriteLine();
        Exception newEx = new Exception("This exception is thrown in B", ex);
        throw newEx;
    }
}

private static void C()
{
    D();
}

private static void D()
{
    Exception ex = new Exception("This exception is thrown in D");
    throw ex;
}

I’ve added some extra bits to the Main method to show the InnerException details too. The output of the program now looks like this:

Method C() catches the exception and partly handles it

This exception is thrown in D
   at ConsoleApplication1.Program.D() in d:DevelopmentConsoleApplication1Cons
oleApplication1Program.cs:line 56
   at ConsoleApplication1.Program.C() in d:DevelopmentConsoleApplication1Cons
oleApplication1Program.cs:line 50
   at ConsoleApplication1.Program.B() in d:DevelopmentConsoleApplication1Cons
oleApplication1Program.cs:line 36

This exception is thrown in B
   at ConsoleApplication1.Program.B() in d:DevelopmentConsoleApplication1Cons
oleApplication1Program.cs:line 44
   at ConsoleApplication1.Program.A() in d:DevelopmentConsoleApplication1Cons
oleApplication1Program.cs:line 29
   at ConsoleApplication1.Program.Main(String[] args) in d:DevelopmentConsoleA
pplication1ConsoleApplication1Program.cs:line 14

As you can now see all the information is available. It can now be seen the patch from the final point the exception was caught to the point it was originally thrown.

Solution 2: Re-throwing the Exception

If you do not have any additional information to add to the exception you can simply use the throw keyword on its own and it will keep the existing exception object without altering it. For example:

try
{
    // Do something that might cause an exception
}
catch (Exception ex)
{
    // Some stuff
    throw;
}

Changing our program above to use the throw statement on its own will mean the program now looks like this:

static void Main(string[] args)
{
    try
    {
        A();
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
        Console.WriteLine(ex.StackTrace);
    }
    Console.ReadLine();
}

private static void A()
{
    B();
}

private static void B()
{
    try
    {
        C();
    }
    catch (Exception ex)
    {
        // I can do something
        Console.WriteLine("Method C() catches the exception and partly handles it");
        Console.WriteLine();
        throw;
    }
}

private static void C()
{
    D();
}

private static void D()
{
    Exception ex = new Exception("This exception is thrown in D");
    throw ex;
}

And the output now looks like this:

Method C() catches the exception and partly handles it

This exception is thrown in D
   at ConsoleApplication1.Program.D() in d:DevelopmentConsoleApplication1Cons
oleApplication1Program.cs:line 52
   at ConsoleApplication1.Program.C() in d:DevelopmentConsoleApplication1Cons
oleApplication1Program.cs:line 46
   at ConsoleApplication1.Program.B() in d:DevelopmentConsoleApplication1Cons
oleApplication1Program.cs:line 40
   at ConsoleApplication1.Program.A() in d:DevelopmentConsoleApplication1Cons
oleApplication1Program.cs:line 26
   at ConsoleApplication1.Program.Main(String[] args) in d:DevelopmentConsoleA
pplication1ConsoleApplication1Program.cs:line 14

As you can see the stack trace now shows you the entire route between the point the exception was caught and when it was thrown. We can also see from the message that the method C still caught and partly handled the exception.

Using the throw keyword like this actually translates to the CIL (MSIL) rethrow command. When you use throw with an Exception object it translates to the CIL throw command.

When the exception is thrown in D the CIL looks like this:

.method private hidebysig static void D() cil managed
{
    .maxstack 2
    .locals init (
        [0] class [mscorlib]System.Exception ex)
    L_0000: nop
    L_0001: ldstr "This exception is thrown in D"
    L_0006: newobj instance void [mscorlib]System.Exception::.ctor(string)
    L_000b: stloc.0
    L_000c: ldloc.0
    L_000d: throw
}

The key above is L_000d where it throws the exception.

Compare that to method B:

.method private hidebysig static void B() cil managed
{
    .maxstack 1
    .locals init (
        [0] class [mscorlib]System.Exception ex)
    L_0000: nop
    L_0001: nop
    L_0002: call void ConsoleApplication1.Program::C()
    L_0007: nop
    L_0008: nop
    L_0009: leave.s L_0020
    L_000b: stloc.0
    L_000c: nop
    L_000d: ldstr "Method C() catches the exception and partly handles it"
    L_0012: call void [mscorlib]System.Console::WriteLine(string)
    L_0017: nop
    L_0018: call void [mscorlib]System.Console::WriteLine()
    L_001d: nop
    L_001e: rethrow
    L_0020: nop
    L_0021: ret
    .try L_0001 to L_000b catch [mscorlib]System.Exception handler L_000b to L_0020
}

In the above CIL code the key is L_001e where it rethrows the exception. This is where the CIL is much more explicit than C#. In C# the throw keyword is overloaded and functions differently depending on whether it receives an exception object or not.

Drawing lines on the map with the Virtual Earth ASP.NET control

This uses the July 2008 CTP of the Windows Live tools. You can download the Windows Live Tools for Visual Studio.

In this post, we’re taking a look at drawing lines on the map with the Virtual Earth ASP.NET control.

In the a previous post (Using PushPins with the Virtual Earth ASP.NET control) I showed how to create a Shape object that represents a point on the map. In that post the Shape constructor took a parameter that described the type of object and a point. With Polylines more than one point is required. To construct an appropriate Shape object a list of points is needed. A point is represented by an LatLongWithAltitude object.

List<LatLongWithAltitude> points = new List<LatLongWithAltitude>();

Once the list is populated the Shape can be created:

Shape result = new Shape(ShapeType.Polyline, points);

Alternatively, it is possible to defer the addition of the points until a later time by assigning them through the Points property.

Lines and Pushpins

One thing you have to be careful of when creating shapes that are lines (or polygons, but we’ll come to that later on) is that by default a pushpin is also displayed to go along with the line (see right) in order to give the user something to hover over so they can gain more information. If these pushpins are not desired then the IconVisible property needs to be set to false.

shape.IconVisible = false;

On the other hand, if a pushpin is desired for each line then you can control where the pushpin appears. By default they are somewhere along the middle of the line. The IconAnchor property can be set to the point at which the pushpin is to appear. For example, to set the pushpin to appear at the start of a line use:

shape.IconAnchor = shape.Points[0];

You can also do the other customising of the pushpin as I showed you in my previous post (Using PushPins with the Virtual Earth ASP.NET control).

Customising the Line

There are also many ways to customise the line as well. You can change the colour and width of the line on the Shape object.

In the example on the left the data has been customised to reflect two attributes. The data is rail services in Scotland and includes information on the route, start and end stations, the length of the route and the train franchise operator.

In the example, the train franchise operator is reflected in the colour of the lines while the length of the route is reflected in the width of the line. The shorter suburban routes are quite thin lines, while the intercity lines are much thicker.

The LineWidth property accepts the width in pixels of the line, while the LineColor property accepts a Color object (from the Microsoft.Live.ServerControls.VE namespace). The Color object allows you to specify the standard red, green and blue values (each 0-255) along with an alpha blend value (a double from 0 to 1.0).

Line Generalisation

So far this is pretty easy, however, what appears on the map isn’t necessarily what you put into the Shape object. Virtual Earth generalises the shape that you create, presumably to improve performance. I suspect the idea was to generalise in a way that the user wouldn’t notice, however, it some situations it is very obvious that the line is not displaying its original points.

Take a look at these two maps. They both display exactly the same data. One is just a zoomed in version of the other (I’ve enlarged the zoomed out version so they are the same size to make them easier to compare).

The map on the left shows the naturally zoomed in version. The one on the right shows the zoomed out version (which I then resized back so that both maps are the same size for this blog post)

Because central Scotland is quite busy and has a lot of rail routes, have a look at the routes in the Highlands (north of Scotland) to see this phenomenon more easily. Take the most northern route for example. The map on the left shows it weaving in and out of the mountains reasonably clearly, while the map on the right shows the route slightly more straightened out. Also the map on the right doesn’t even appear to hit some of the points.

 

Technorati Tags: ,,

Using a different map server with the Virtual Earth ASP.NET controls.

This uses the July 2008 CTP of the Windows Live tools. You can download the Windows Live Tools for Visual Studio.

One of the interesting features of Virtual Earth is that it doesn’t have to use the maps provided by Microsoft. You can set it up to point to another tile server so that you can use your own maps. This could be extremely useful for people who want to show static visualisations of data, or simply display something different to what Microsoft give you.

Setting up the tile server is likely the more difficult part as setting up the client to point at a new tile server is incredibly easy. I’m not going into setting up the tile server in this post.

First setting up the ASPX page to handle this:

<form id="form1" runat="server">
    <div>
       <asp:ScriptManager ID="ScriptManager1" runat="server"
         EnablePartialRendering="true" />
       <ve:Map ID="VEMap" runat="server" Height="600px" Width="600px"
         ZoomLevel="8" Center-Latitude="55.75" Center-Longitude="-3.5" />
    </div>
</form>

As you can see there isn’t anything unusual here. There are no additional options to set.

However, in the Page_Load event handler there are some things that need to be set up:

protected void Page_Load(object sender, EventArgs e)
{
    VEMap.DashboardSize = DashboardSize.Tiny;
    List<LatLongRectangle> bounds = CalculateBounds();
    TileSourceSpecification tileSpec = new TileSourceSpecification(
        "OSM", "", 1, bounds, 1, 18, "getTilePath", 1.0, 100, true);
    VEMap.AddTileLayer(tileSpec, true);
}
private static List<LatLongRectangle> CalculateBounds()
{
    List<LatLongRectangle> bounds = new List<LatLongRectangle>();
    LatLongRectangle box = new LatLongRectangle(
        new LatLong(90, -180), new LatLong(-90, 180));
    bounds.Add(box);
    return bounds;
}

First of all, we are reducing the dashboard side down to its minimum because the particular tile server does not support the other features provided in the dashboard such as switching between road and aerial photography.

We create the TileSourceSpecification that defines what the tile server can do and how to interact with it. The parameters are:

  • Id: An identifier for you to use to identify the tile server, if you are using more than one.
  • TileSource: You can set up a string format to define the URL of the tiles, but only if your tile server is using the same naming convention as Virtual Earth itself. It has the ability of switching between road, aerial and hybrid modes and load balancing. More info on the TileSource Property…
  • NumServers: If your tile server is load balanced then this specifies the number of servers.
  • Bounds: This is the bounding box of the tile layer. In our case above the tile server covers the entire world so our bounding box covers +90,-180 to -90,+180
  • MinZoomLevel / MaxZoomLevel: This pair of parameters specify the the minimum and maximum zoom levels. 1=the whole world, 18 = street level.
  • GetTilePath: This is the name of a javascript function that generates the path to the tile. I’ll go into more detail on that javascript function a little later on. However, if this property contains a value then the TileSource and NumServers properties are ignored.
  • Opacity: How opaque is this tile layer. By default the Virtual Earth tiles are drawn first, then your layer is drawn on top. 0 is completely transparent (and a bit pointless) while 1.0 is completely opaque and will hide the layer underneath. At present you cannot turn off the layer underneath so if you only want to see your layer set the opacity to 1.0. This is because Virtual Earth ASP.NET controls are based on Virtual Earth 6.1. 6.2 is now released which does have the ability to turn off the base layers.
  • ZIndex: Tile layers can be stacked on top of each other, this indicates the positioning of this layer in that stack.
  • Visible: Indicates whether the layer is visible or not.

In the example above the tile server does not support the virtual earth naming convention. In that case a javascript function to define the name of each tile is needed. In our example it looks like this:

function getTilePath(tileContext)
{
    return "http://tile.openstreetmap.org/" + tileContext.ZoomLevel +
         "/" + tileContext.XPos + "/" + tileContext.YPos + ".png";
}

The server for the tiles is http://tile.openstreetmap.org. If you are unfamiliar with it, Open Street Map is an open source map of the world.

The tile server refers to the individual tiles in the format “/{ZoomLevel}/{X}/{Y}.png”. These values can be obtained by the tileContext parameter (see right) passed into the javascript function.

The tile context also contains a map style property which can be “r” (road), “a” (aerial) or “h” (hybrid).

The final result looks like this:

For information about doing the same purely in javascript see this post by John O’Brien.