Unsung heroes in .NET 4

It’s been a while since I blogged as I’ve mainly been updating an existing application to use .NET 4, so there has not been anything of massive substance that has inspired me.  However, I have been impressed by some of the lovely ‘simplifications’ introduced in this version of the framework.

There is a wealth of new features in this version of the framework, ranging in size from major additions like MEF and EF4 through to seemingly minor items like Dynamic.  Here are some of my favourites, starting with the better known additions, and ending up with the smaller unsung heroes you really need to take note of:

Managed Extensibility Framework (MEF)

I love MEF due to its simplicity.  It’s lightweight, and a standard part of the framework so no extra bulk required in your deployment package.  I’m not going to repeat what plenty of others have written on this subject, but I’d recommend checking out what Jeremy Likeness has to say on the subject, and also Kent Boogaart.

Entity Framework Version 4 (EF4)

Compared to the initial version of EF, EF4 is soooo much better and if you haven’t yet checked it out: do so!  I personally love the Model First approach, and the way you can then generate your database schema from this; this allows you to be database agnostic.  Again, lots of information out there on this one, but aside from the main site link I would suggest looking at some of the following:-

Also, Julie Lerman has a good blog that covers EF, as well as being the author of a book and the videos you see in the main MSDN site.

Windows Communication Foundation (WCF) 4

For me the beauty of this version of WCF is the simplification in configuration and increase in performance…with minimal effort you can reduce configuration and make it simpler/easier to maintain…and with no effort, you get a performance boast due to optimisations they have made.

WCF Data Services

Again, lots is being written about this technology and rightly so; very cool/powerful whilst remaining simple. You can see what’s new here, and please take a look at what Felix has to say on this subject (it’s one he’s VERY passionate about).

Parallel Programming

OK, we’re finally getting to the part where I write something rather than providing you with a brief comment and a set of links ;-)

I have always had a love of parallel programming that stems from my days developing in C++. Process, threads, fibers, locking, contexts, etc. all add another dimension to programming that I enjoy, so the additions made to Parallel programming in the .NET Framework are something I’m ‘possibly’ biased towards ;-)

I’m equally aware that there are quite a few developers around that are ‘put off’ using this technology as they find it too fine-grained/difficult/confusing.

I would highly recommend that you take a look at the wonderful balance the team at Microsoft have put into the Task library: it is both simple and flexible and is my personal favourite find in this new version of the framework.  They have managed to make the syntax so sweet, that you can quickly write code that is easy to understand whilst performing tasks asynchronously that would previously have been a far more arduous affair.

When you combined it with the simplicity of lambda expressions, the result is short, sweet, and I think elegant (subjective I know!):

C#
Task.Factory.StartNew(() => GetData(), CancellationToken)              
    .ContinueWith(t => UpdateView(), CancellationToken,
        TaskContinuationOptions.NotOnCanceled, MainUIScheduler);

So the above code simply performs the GetData() call on a thread, and when it finishes, we continue onto a subsequent task…that being, UpdateView() which needs to occur on the UI context.

Note: I typically define a CancellationToken (new CancellationTokenSource()) and the MainUIScheduler (TaskScheduler.FromCurrentSynchronizationContext()) at a higher level so that I can share the same cancellation token (e.g. when I want to terminate), and avoid repeatedly making a call to get the UI context.

You can continue to chain extra calls on, and/or nest other calls…there’s a lot of power/flexibility to be had here.

Here’s another example that executes a number of tasks to get data, and then waits on all of these before continuing with another task:

C#
var areasTask = Task.Factory.StartNew(() =>
    _areas = _metadataService.ListActiveEntities<BE.SpecialityArea>(),
        CancellationToken)
    .ContinueWith(task => _positionEditor.Areas = _areas, CancellationToken,
        TaskContinuationOptions.NotOnCanceled, MainUIScheduler);
var classesTask = Task.Factory.StartNew(() =>
    _classes = _metadataService.ListActiveEntities<BE.Class>(),
        CancellationToken)
    .ContinueWith(task => _positionEditor.Classes = _classes, CancellationToken,
        TaskContinuationOptions.NotOnCanceled, MainUIScheduler);
var shiftsTask = Task.Factory.StartNew(() =>
    _shifts = _metadataService.ListActiveEntities<BE.Shift>(),
        CancellationToken)
    .ContinueWith(task => _positionEditor.Shifts = _shifts, CancellationToken,
        TaskContinuationOptions.NotOnCanceled, MainUIScheduler);
var topicsTask = Task.Factory.StartNew(() =>
    _topics = _metadataService.ListActiveEntities<BE.Topic>(),
        CancellationToken)
    .ContinueWith(task => _positionEditor.Topics = _topics, CancellationToken,
        TaskContinuationOptions.NotOnCanceled, MainUIScheduler);                     

Task.Factory.ContinueWhenAll(new Task[] { areasTask, classesTask, shiftsTask, topicsTask },
    task => { _positionEditor.SelectedPosition = new BE.PlacementPosition(); },
    CancellationToken, TaskContinuationOptions.None, MainUIScheduler);

When I say ‘wait’ I should clarify that it does not block the main thread context, so whilst we are obtaining data and setting on the UI, we are still able to let the main thread flow…

Dynamic Language Runtime

I was originally not sure how useful this addition would be, and I suspect I will not be using it greatly but it is definitely a useful addition.  Dynamic allowed me to easily and efficiently replace some invoke code.  The result is code that is shorter, easier to maintain, easier to read, and performs well…all pluses in my book! :-)

Here’s a before and after example:

C# BEFORE
private static ConcurrentDictionary<Type, RuntimeMethodHandle> _channelMethodDictionary
    = new ConcurrentDictionary<Type, RuntimeMethodHandle>();

private static MethodBase GetChannelMethod(Type type)
{            
    RuntimeMethodHandle handle;

    if (_channelMethodDictionary.ContainsKey(type))
    {
        handle = _channelMethodDictionary[type];
    }
    else
    {
        MethodInfo methodInfo = type.GetMethod("CreateChannel", new Type[] { });
        handle = methodInfo.MethodHandle;
        _channelMethodDictionary.TryAdd(type, handle);
    }

    return MethodInfo.GetMethodFromHandle(handle, type.TypeHandle);
}

private static IMetadataService<T> GetChannel<T>(ChannelFactory factory) where T : MetadataEntity
{           
    MethodBase mb = GetChannelMethod(factory.GetType());

    return mb.Invoke(factory,
        BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance
            | BindingFlags.ExactBinding,
        null, null, null) as IMetadataService<T>;     
}

C# AFTER
private static IMetadataService<T> GetChannel<T>(dynamic factory) where T : MetadataEntity
{
    return factory.CreateChannel() as IMetadataService<T>;                   
}

Reflection and invocation are areas that we have previously had to put in ‘more effort’ as you can see from the original code.  A great article on this subject is called: Dodge Common Performance Pitfalls to Craft Speedy Application.

I was impressed how using DLR performs, and can see in my project that it stands up to the claim that it provides fast dynamic dispatch and invocation. 

Print | posted on Friday, 30 July 2010 2:33 PM

Feedback

# re: Unsung heroes in .NET 4

left by Alex at 16/02/2012 7:46 PM Gravatar
This is definitely good content …for sure…. it's awesome to see that you are posting some unique stuff here!
Title  
Name
Email (never displayed)
Url
Comments   
Please add 4 and 5 and type the answer here: