Not all of our event handlers contain massive amounts of code, every now and again all we want is a line or two of code. With anonymous delegates we can write our event handlers inline, saving us creating new methods for just a couple of lines. There is an argument that a simple inline event handler is easier to read and follow. I’ve seen more and more using this technique, just make sure its not abused.

yellow.Click += new RoutedEventHandler(delegate(object s, RoutedEventArgs re) { gshape.Fill = Brushes.Yellow; });

Visual Studio 2008 has only been out the door 5 minutes and there is a whole load of new technologies and CTPs flying out of the door. You barely get a chance to catch your breath the speed some of these are appearing.

Like most people I don’t have time to look at all of the new stuff on the horizon. But I’m most interested in:

Parallel Extensions to .Net Fx. I want to spend some time looking at this, i’ve got an interest in parallel programming and I really want to see what they’ve done here and how easy it makes it to make use of all those cores.

ASP.Net MVC. I been doing mainly WinForms and WPF work recently. Its been a little while since I did any ASP.Net so I really want to see how well this works. I did a bit of MVC when I had a dabble at Cocoa programming on the Mac. It’ll be intersting to see how ASP.Net MVC stacks up against the original asp.net page model. 

As I have a play with these i’ll post up a few musings and i’ll see if I can do something cool with them.

Yes it is you say. Well you can do this:

msbuild mysolution.sln

and it does work. It will build all of your solution but it is not a true MsBuild file in the MsBuild format. The MSBuild engine has special code to deal with them. What it is actually doing is transforming the solution into a MsBuild file and running that.

Before you run it try this at the command prompt:

Set MSBuildEmitSolution = 1

This sets a special environment variable that MSBuild checks, if its set then it emits a copy of the transformed solution. Open this up and you will see what is happening when your build your solution. Its not very complicated, mainly just a bunch of calls to the MSBUILD task for the projects in the solution.

MSBuild Transforms

November 4, 2007

Passing a list of items to a task is pretty straightforward in MSBuild. Consider a simple itemgroup which contains a bunch of files.

<ItemGroup>
    <MyFiles Include="C:\Windows\Microsoft.NET\Framework\v2.0.50727\1033\*"/>
</ItemGroup>

We can call a task and pass our files as a list using @(MyFiles).

<Message Text="@(MyFiles)"/>

Target Build:
    C:\Windows\Microsoft.NET\Framework\v2.0.50727\1033\alinkui.dll;C:\Windows\Mi
crosoft.NET\Framework\v2.0.50727\1033\cscompui.dll;C:\Windows\Microsoft.NET\Fram
ework\v2.0.50727\1033\CvtResUI.dll;C:\Windows\Microsoft.NET\Framework\v2.0.50727
\1033\vbc7ui.dll;C:\Windows\Microsoft.NET\Framework\v2.0.50727\1033\vjscui.dll;C
:\Windows\Microsoft.NET\Framework\v2.0.50727\1033\vjslibui.dll;C:\Windows\Micros
oft.NET\Framework\v2.0.50727\1033\Vsavb7rtUI.dll
    alinkui;cscompui;CvtResUI;vbc7ui;vjscui;vjslibui;Vsavb7rtUI

Build succeeded.
    0 Warning(s)
    0 Error(s)

We may not always want to pass in the full file name and path, what we might want to pass is item metadata. This is where MSBuild transforms come in. They let us change which pieces of information are used in the construction of the list. The syntax takes the form of @(itemgroup->’%(itemmetadata)’)

We can pass a just the file names (no extension) taken from the FileName well known item metadata.

<Message Text=@(MyFiles->’%(FileName)’)/>

alinkui;cscompui;CvtResUI;vbc7ui;vjscui;vjslibui;Vsavb7rtUI

or the file name and extension

<Message Text="@(MyFiles->'%(FileName)%(Extension)')"/>

alinkui.dll;cscompui.dll;CvtResUI.dll;vbc7ui.dll;vjscui.dll;vjslibui.dll;Vsavb7rtUI.dll

or we might want to pass the list of files but with a different extension.

<Message Text="@(MyFiles->'%(FileName).data')"/>

alinkui.data;cscompui.data;CvtResUI.data;vbc7ui.data;vjscui.data;vjslibui.data;Vsavb7rtUI.data

MSBuild tasks can handle a list of files in several ways. Many of them will take them all in one go, through a single attribute. The list comes through as ITaskItem[] inside the task itself. We may not always want to call the task in this way, and not all support this. In some scenarios we might want to call the task once for each file.

Lets start by creating an itemgroup that defines all our files. Were going to give it the Name MyFiles and we’ll use a wildcard on the include attribute to select all the files in a directory.

<ItemGroup>
    <MyFiles Include="C:\Windows\Microsoft.NET\Framework\v2.0.50727\1033\*"/>
</ItemGroup>

A lot of targets in MSBuild can take a list seperated by semicolons. the CSC task for the C# compiler can take a list of source files in this way. To pass our list of files in this way we use the @(itemgroup) syntax, like this:

<Message Importance="normal" Text="@(MyFiles)"/>

In this example with the message task we our passing a single string with all our filenames seperated by semicolons.

Often what we actually want to do is call the task once for every file in the itemgroup. To do this we use the %(itemgroup.itemmetadata) syntax. In our itemgroup we haven’t defined any item metadata, fortunately msbuild provides some well known item metadata for us automatically. This includes such things as the file name, path, extension.

<Message Importance="normal" Text="%(MyFiles.FullPath)"/>        

Here we will call the message task once for every file and we will pass the full path.

The whole msbuild file:

<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <ItemGroup>
        <MyFiles Include="C:\Windows\Microsoft.NET\Framework\v2.0.50727\1033\*"/>
    </ItemGroup>
        
    <Target Name="Build">
        <!--Pass all in one call ';' seperated-->        
        <Message Importance="normal" Text="@(MyFiles)"/>

        <!--Call Target once for each file-->
        <Message Importance="normal" Text="%(MyFiles.FullPath)"/>        
    </Target>    
</Project>

When we run it with msbuild, we firstly get the output from the first call to the message task which received the text as a single string seperated by ‘;’. After this we have the output where it called the message target once for each file.

__________________________________________________
Project “C:\Temp\multiple.xml” (default targets):

Target Build:
    C:\Windows\Microsoft.NET\Framework\v2.0.50727\1033\alinkui.dll;C:\Windows\Mi
crosoft.NET\Framework\v2.0.50727\1033\cscompui.dll;C:\Windows\Microsoft.NET\Fram
ework\v2.0.50727\1033\CvtResUI.dll;C:\Windows\Microsoft.NET\Framework\v2.0.50727
\1033\vbc7ui.dll;C:\Windows\Microsoft.NET\Framework\v2.0.50727\1033\vjscui.dll;C
:\Windows\Microsoft.NET\Framework\v2.0.50727\1033\vjslibui.dll;C:\Windows\Micros
oft.NET\Framework\v2.0.50727\1033\Vsavb7rtUI.dll

    C:\Windows\Microsoft.NET\Framework\v2.0.50727\1033\alinkui.dll
    C:\Windows\Microsoft.NET\Framework\v2.0.50727\1033\cscompui.dll
    C:\Windows\Microsoft.NET\Framework\v2.0.50727\1033\CvtResUI.dll
    C:\Windows\Microsoft.NET\Framework\v2.0.50727\1033\vbc7ui.dll
    C:\Windows\Microsoft.NET\Framework\v2.0.50727\1033\vjscui.dll
    C:\Windows\Microsoft.NET\Framework\v2.0.50727\1033\vjslibui.dll
    C:\Windows\Microsoft.NET\Framework\v2.0.50727\1033\Vsavb7rtUI.dll

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:00:00.05

Being a proud owner of a Canon EOS 5D one of the first things I did after getting a new 64bit Vista machine was to go get the imaging codec from Canon for their digital SLR’s.

My enthusiasm was quickly destroyed when I found out that it was 32bit only. Fast forward a few months and Canon have just released a new version of the Codec that adds support for the likes of the 1D Mark III. But still no Vista 64 support. Come on Canon, sort this out. You’ve gone to the effort to write the codec, spend a little bit more effort to create a 64bit version. As our favourite pub land-lord would say: Shame on you Canon, Shame on you.

Here’s hoping you fix this for the next version.

Oh, and its not just Canon that doesn’t know Vista 64 bit exists, Nikon are just as bad.

WPF in the Enterprise

October 31, 2007

Most software developers don’t create off the shelf software packages, I’d hazard a guess that very few do. The reality is that most developers work on Line of Business applications, these are applications that have a user base measured in the hundreds, or the low thousands if your lucky. These are the applications where WPF needs to gain some traction.

These LOB applications are built to solve a business need and the sad fact about them is that the vast majority of them are ugly. There aren’t many Miss Worlds in the LOB realm.

If you take your average WinForms LOB application you’ll find a UI that is put together with minimal thought to the aesthetics. They’ll be a whole host of usability crimes and the visual style will be based around whatever the custom control package they’re using provides. The thing as a whole will have a lack of visual cohesion, which will be a function of the number of developers who worked on it. Its sad but true that most developers are rubbish at designing good UI’s.

Creating the UI for an average LOB application is fairly straightforward with Windows Forms. Everything we need is usually there. The tools, the framework and the environment are suited to the job at hand. Now this is the world where WPF has to live and thrive.

Here are some of my observations.

WPF is harder than WinForms.

There learning curve is steeper. Routed Events, dependency properties etc are not straight forward. Its not easy to pick up WPF quickly, and there isn’t much of your WinForms knowledge that has a high relevance in the world of WPF. Starting a new project with a team that hasn’t developed with WPF is going to require a reasonable amount of time to let them get up to speed with the technology.

Tool support is lacking.

The WinForms designer is very good. It’s intuitive to use and most people can just work it out without any intervention. The WPF designer in Visual Studio 2008 just isn’t up to the same standard. Lets look at the property windows for a button in the WinForms designer and the VS WPF Designer:

Windows Forms:

image

WPF:

image

To me Windows Forms is more intuitive, where are the events in VS WPF Designer, what the hell am I supposed to type in the BitmapEffectInput or Opacity mask properties? Where is the ‘…’ button that gives a dialog for setting these.

Its not all doom and gloom for WPF. Expression Blend is great, it works really well and is very stable. I know that Blend is pitched at designers but I think its great for developers too. Why did they create two designers; why doesn’t Visual Studio host a variant of the blend engine. They’ve done it for the Web designer in VS2008, that’s based on the core engine from Expression Web.

We don’t have designers

One of the big points that Microsoft wanted to get across when evangelizing WPF was the designer developer seperation and how WPF let them both easily co-exist within a project. For most LOB applications the developer is the designer. The problem is that they often have zero design ability. Eric Sink had a great post about WPF’s dirty secret, there is no golden ticket to a beautiful UI. Its just as easy to create an ugly app in WPF as it is with WinForms. There is no substitute for a bit of real graphical talent.

At times WPF makes it to easy to commit crimes against usability. Take Animation, its relatively straightforward to implement. But just because you can doesn’t mean that you should.

Here’s an idea, how about some pre-rolled styles with Visual Studio. The kind of thing that can be used to jazz up an otherwise dull application.

They rejected the animated 3D feature, they just want a grid instead.

Lets be honest, 3D is great and I love the fact that its so simple in WPF (well at least compared to the other ways of doing 3D). We want to create something that lets us play with these new features and dangle our feet in the world of quaternions but what we normally end up having to implement is a grid. Now the WPF grid is… yes, we all know there isn’t one.

Now I’m not trying to knock WPF. I think its a great technology. Its full of some amazing features and technologies: 3D, improved data binding, scalable UI’s, hardware rendering, proper text rendering, animation, documents and so on. It just isn’t going to automatically replace Windows Forms, there is still work that needs to be done to make it the default choice for every new project that involves some kind of desktop app. Its good to see announcements like the WPF Composite Client, these are the sort of things that we need to drive the adoption forward.

Hosting MSBuild

October 29, 2007

Most people tend to use MSBuild via a few standard scenarios. Inside Visual Studio, from the command line and invoked by a continuous integration system such as Cruise Control are probably the most common.

The MSBuild framework is very flexible and we can very easily host the build engine ourselves with very little effort.

All we need to do is:

Add a reference to the MsBuild engine and framework.

image

Its often a good idea to run MSBuild in its own thread. If your application is running in an MTA thread then you’ll need to do this otherwise you will get a lot of warnings. If you want to see this try creating a Powershell script that invokes MSBuild through .net rather than calling msbuild.exe.

Create and invoke the engine:

Engine engine = new Engine();
engine.BinPath = @"C:\Windows\Microsoft.NET\Framework\v2.0.50727\";

ConsoleLogger logger = new ConsoleLogger();

engine.RegisterLogger(logger);

bool result = engine.BuildProjectFile(
    @"C:\Projects\MyProj.csproj",
    "Build");

if (result)
{
    MessageBox.Show("Build Suceeded");
}
else
{
    MessageBox.Show("Build Failed");
}

There are two loggers that come with the base framework, the ConsoleLogger and FileLogger. Its pretty obvious from there names as to what they do. If we are hosting msbuild then chances are they won’t meet all of there needs. Fortunately we can roll our own fairly easily by implementing the ILogger interface.

public class MyLogger : ILogger

Then set up some events to handle all of the logging.

public void Initialize(IEventSource eventSource)
{
    eventSource.ProjectStarted += new ProjectStartedEventHandler(eventSource_ProjectStarted);
    eventSource.TaskStarted += new TaskStartedEventHandler(eventSource_TaskStarted);
    eventSource.MessageRaised += new BuildMessageEventHandler(eventSource_MessageRaised);
    eventSource.WarningRaised += new BuildWarningEventHandler(eventSource_WarningRaised);
    eventSource.ErrorRaised += new BuildErrorEventHandler(eventSource_ErrorRaised);
    eventSource.ProjectFinished += new ProjectFinishedEventHandler(eventSource_ProjectFinished);

}

Write some handlers for these events. This is where we get the details of the error/warning/message and handle it as we please. It this example we are just writing it to the debug output window.

void eventSource_WarningRaised(object sender, BuildWarningEventArgs e)
{
    //Handle the logging event
    System.Diagnostics.Debug.WriteLine(e.Message);            
}

WPF is very similar to Windows Forms in terms of its multi threaded capabilities. While it does use multiple threads as part of the rendering pipeline as far as a user of WPF is concerned the UI is single threaded. So the old rule that we must do all of our UI updates from the main thread still applies.

In Windows Forms we would use Control.Invoke to send work back to our main thread. WPF is very similar. It provides the Dispatcher which allows us to Invoke back onto the main thread.

Its reasonably straight forward to use. We provide a delegate that we would like to run on the main thread, and ask the Dispatcher to run it using either Invoke (for synchronous running) or BeginInvoke (for async running).

Consider the following example. We have a simple window with a label and on startup we create a thread that simulates a long running task (in this case calculating Pi, with a few sleeps to slow it down). The thread will then use the Dispatcher to periodically update the UI with its progress.

Xaml:

<Window x:Class="DispatcherApp.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="111" Width="535">
    <Grid>
        <Label Margin="13,22,19,24" Name="label1">Label</Label>
    </Grid>
</Window>

C#:

using System;
using System.Windows;
using System.Threading;

namespace DispatcherApp
{
    delegate void UpdateTheUI(string newText);

    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();

            Thread thrd = new Thread(new ThreadStart(this.CalculatePi));
            thrd.Start();
        }

        void CalculatePi()
        {
            double res = 0.0;
            for (int i = 0; i < 20; i++)
            {
                Thread.Sleep(1000);
                
                res += Factorial(2 * i) /
                    (Math.Pow(Factorial(i), 2) * ((2 * i) + 1) * Math.Pow(16, i));

                string piText = (res * 3.0).ToString();

                this.Dispatcher.BeginInvoke(
                    System.Windows.Threading.DispatcherPriority.Normal,
                    (UpdateTheUI)delegate(string text)
                    {
                        label1.Content = text;
                    }, piText);

            }

        }

        double Factorial(long value)
        {
            long returnVal = 1;
            for (long i = 2; i <= value; i++)
            {
                returnVal *= i;
            }
            return (double)returnVal;
        }

    }
}

Its worth noting that there are other ways to do this in WPF. The BackgroundWorker provides similar capabilities and might be more appropriate in some circumstances.

ReaderWriterLock Reborn

October 19, 2007

It turns out the ReaderWriterLock has a few flaws, it’s not that it doesn’t work. It just doesn’t work as well as it should. Microsoft have admitted its not as good as it could be and have provided another Reader-Writer lock implementation in .net 3.5 called ReaderWriterLockSlim.

They have decided not to change the existing ReaderWriterLock for backwards compatibility issues, instead we have two versions. For virtually all use cases we should be switching to the new ReaderWriterLockSlim but there are a few subtle differences which can affect which one we choose.

ReaderWriterLock

  • Is slow, about 6-7x slower than a Monitor.Enter
  • Favors read locks, if you have lots of read lock requests then it can prove difficult for a write to get a lock. Depending on how many of which type of lock gets requested you can end up with a situation where your Write requests are waiting a long time.
  • Upgrading a reader to a writer is not atomic.

Jeff Richter has a great MSDN article about its deficiencies.

ReaderWriterLockSlim

  • Is much quicker, only 2x slower than a Monitor.Enter.
  • Favors writes over reads.
  • Upgrades from reader to writer are atomic.

And the cons, which will determine if we should be using the original.

  • Doesn’t handle ThreadAbort exceptions or Out Of Memory Exceptions very well. Can end up pegging the CPU at 100%. This should not really be much of an issue in practice since we shouldn’t really be forcing aborts that raise thread abort exceptions and out of memory exceptions are extremely difficult to recover from anyway.
  • Not suitable for use in hosted CLR scenarios such as SQL Server, use the original if you want to run your code inside of SQL server.