Book Review: .NET 4.5 Parallel Extensions Cookbook

.NET 4.5 Parallel Extensions Cookbook

Here’s my quick review of a new book, .NET 4.5 Parallel Extensions Cookbook by Bryan Freeman.

The book launches straight in to fairly long code examples, so it would be best if you’ve already got some basic experience using Tasks.

The book’s chapters are divided into sections providing many examples of the following topics:

  • The Task Parallel Library (TPL)
  • Parallel LINQ (PLINQ)
  • The new BCL concurrent collections and producer/consumers
  • Thread synronchronization primatives
  • The new Visual Studio parallel profiling and debugging windows
  • Async and await keywords
  • The new .NET Dataflows library

Reasons why you should read this book

If you already have basic familiarity with Tasks, but you aren’t sure the difference between:

  • Task.Start() and Task.Factory.StartNew()
  • Different TaskCreationOptions
  • Different ParallelMergeOptions for parallel LINQ queries

Or, if you’re not sure about:

  • The correct semantics around throwing OperationCancelledException
  • How to link multiple CancellationTokens together
  • How to schedule a continuation to execute when a task faults or is cancelled
  • How to break out of Parallel.For()
  • In the BCL concurrent collections, what completeness or a consuming iterator means
  • What is a Barrier and how to use it
  • What BufferBlock, TransformBlock, WriteOnceBlock, BroadcastBlock and JoinBlocks are for, and how they interact with Tasks

Then, like me, you will find this book useful.

Other bits I liked

The chapters on synchronization primatives provide not only an overview of new TPL concepts like Barriers, but also a good coverage of traditional .NET concepts (like Monitor and ManualResetEventSlim) and how they can be used inside Tasks.

The book highlights the very-useful new Visual Studio 2012 concurrency visualizer debugging windows, which can quickly identify performance issues in your program such as deadlocks or excessive context-switching (where one CPU core slows down because it is frequently reloading the cache and stack so it can switch to a different thread). These new features should be essential knowledge for any .NET developer working on multi-threaded code.

I also enjoyed the chapters on the new TPL Dataflow library, which provides a framework for building composable Task-based input/output processing steps, which can be linked together to form a larger sequential pipeline. Unfortunately, the book doesn’t provide many examples of situations when you might want to use Dataflows, but off the top of my head I can think of a couple of places in past projects where they would have been useful:

  • In an e-commerce system: post-order processing e.g. after a user makes a purchase, submitting the order to fulfilment, accounting, invoicing, analytics and other downstream systems.
  • In a trading/finance market risk analysis system: enriching trade positions through a series of steps that calculate their various different types of risk exposures (including calculations which can be quite CPU intensive) plus fetching other related information (OLAP dimensions) about the trade from other systems (which can involve IO-bound remote service/database calls).

Bits I didn’t like

It would have been nice if the author had further explored how Tasks can be used together with other popular .NET libraries, for example:

  • How Tasks compare to Reactive Extensions (Rx)?
  • How to create an IObservable event stream based on Task completions
  • How you can integrate Tasks into ASP.NET MVC and WebAPI to make scalable asynchronous controllers

The author also uses C_STYLE_CONSTANTS in his code examples — a minor (but annoying) stylistic mistake.

Also be aware the Kindle edition’s fonts are quite a lot smaller than typical books you might purchase from the Amazon store. I had to turn my Kindle display up to size 6 font in order to get an equivalent reading experience from my normal size 2 settings.

Otherwise, I didn’t notice any other serious problems, and would recommend the book as a good entry-level introduction for developers interested in learning more about the TPL.

Book links: Amazon (Paperback), Amazon (Kindle), Amazon (UK), Publisher’s Page

Disclaimer: this review was based on a free promotional copy sent to me by Tania at Packt Publishing.


October 22, 2013 | Leave your comment

Howto: Set up an SSL Offload / Termination Proxy with IIS 7

An SSL termination proxy is a service that sits in front of your web server and converts HTTPS requests to plain HTTP, by offloading the SSL decryption to a separate machine or process. They are commonly used for internet-facing websites, but usually with separate servers. Here’s a quick guide how you can set up your own local SSL termination proxy using IIS to simulate — for development purposes — a production webserver environment.

ssl_termination_proxy

Pre-requisites: Install Rewrite + ARR IIS Features

First, we need to install and enable a couple of IIS features that will make this all work:

  1. Download and install the URL Rewrite and Application Request Routing (ARR) IIS 7 features.
  2. Open the IIS Management Console (inetmgr) > expand your machine > Application Request Routing Cache > right click, Server Proxy Settings… > check Enable Proxy.

Part One: Reverse Proxy Incoming HTTP Requests

Assume we have the following two IIS websites set up:

  1. The real site, containing your app or content, bound on HTTP port :80
  2. The SSL termination proxy, simply a website pointing to an empty directory, bound on HTTPS port :443

First we need to ensure requests arriving at the HTTPS:443 site are proxied through to the HTTP:80 site. We can do this by creating a web.config in the root of the HTTPS:443 IIS site with a single rewrite rule that catches all requests and rewrites them to the HTTP:80 URL:

<configuration>
  <system.webServer>
    <rewrite>
      <rules>
        <rule name="Reverse Proxy" patternSyntax="ECMAScript" stopProcessing="true">
          <match url="(.*)" />
          <!-- Redirect all requests to non-HTTPS site. -->
          <action type="Rewrite" url="http://localhost:80/{R:1}" logRewrittenUrl="true" />
        </rule>
      </rules>
    </rewrite>
    <handlers>
      <clear />
      <!-- No other handlers required. Must clear them otherwise ASP.NET might try to intercept *.svc paths etc. -->
      <add name="Rewrite" path="*" verb="*" modules="RewriteModule" resourceType="Unspecified" />
    </handlers>
  </system.webServer>
</configuration>

Part Two: Block non-HTTP Connections to Deal Service

On the real production hardware, only HTTPS connections will be allowed. We can simulate this on our local IIS by setting up a rewrite rule that will block any request that does not have the X-ARR-SSL HTTP header which indicates it has been routed through ARR.

This rewrite rule should be added to the HTTP:80 site’s web.config:

<system.webServer>
  <rewrite>
    <rules>
      <rule name="Block Non-SSL Requests" patternSyntax="Wildcard" stopProcessing="true">
        <match url="*" />
        <conditions>
          <add input="{HTTP_X_ARR_SSL}" pattern="*|*" negate="true" />
        </conditions>
        <action type="CustomResponse"
                statusCode="403"
                statusReason="Forbidden: This site requires SSL."
                statusDescription="This site is currently configured to only accept connections
                                   through a local SSL termination proxy (IIS Application Request
                                   Routing + Rewrite modules). Any HTTP requests that do not
                                   include a valid X-ARR-SSL header are blocked." />
      </rule>
    </rules>
  </rewrite>
</system.webServer>

The rewrite rule also contains a nice descriptive error message to explain what’s going on if you start getting random 403 errors.

(Note that, as you’ve probably already figured out, anyone can fool this blocking rule by simply populating the X-ARR-SSL header themselves. This is an insecure blocking method that should never be used on production hardware!)

Part Three (Optional): WCF Configuration

If you’re exposing WCF services through the SSL termination proxy, you may need to add the following attribute to your operation contracts:

[ServiceBehavior(AddressFilterMode = AddressFilterMode.Any)]
public class MyService : IMyService
{
    ...
}

Without this attribute WCF will refuse to process requests with a different original URL than what it expects from the binding configuration.

Acknowledgements: This guide was originally based on Ruslan Yakushev’s guide to Reverse Proxy with URL Rewrite v2 and Application Request Routing.


September 24, 2013 | Leave your comment

Microsoft.Web.Administration Confusion

Just a quick tip — if you’re having problems with programmatically modifying your IIS sites configuration using the Microsoft.Web.Administration .NET API, and are currently banging your head against the desk because:

  • ServerManager.Sites returns a completely different set of sites than what is visible in IIS Manager, or
  • No matter how many times you call it, ServerManager.CommitChanges() does not seem to have any visible effect

… then make sure you’re referencing the correct Microsoft.Web.Administration.dll assembly.

Assembly Version Location
Microsoft.Web.Administration.dll v7.0.0.0 C:\Windows\System32\inetsrv\
Microsoft.Web.Administration.dll v7.9.0.0 GAC

What’s the difference? Except for the version number, the two asssemblies look identical, except one (7.9.0.0) only affects IIS Express. You must use v7.0.0.0 if you want to modify IIS. Watch out!


September 22, 2013 | Leave your comment

MVVM async progress meter example using the Task Parallel Library

I’ve just posted up on GitHub a quick example WPF application that shows an MVVM-style progress meter dialog, using the .NET 4.5 Task Parallel Library (TPL). Specifically demonstrating:

  • A progress meter using .NET 4 Tasks (not BackgroundWorkers).
  • Async support.
  • Cancelling of Tasks via CancellationTokens.
  • Exception handling back to the original thread.
  • Reporting background progress updates via IProgress<T>.
  • Tasks can either be declared as void, or have a return value.
  • Progress can be reported from multiple tasks chained together.
  • An injectable, stateless IProgressDialogService, that can be injected for unit testing purposes.
  • Using an attached property to hide the close button in the progress dialog’s title bar using Win32 interop.
  • Using an attached property to implement a close window command using MVVM.

screenshot

It’s based off a blog post by Jürgen Bäurle but converted to use MVVM and the TPL.

You can check it out here: https://github.com/rdingwall/wpf-mvvm-task-progress-dialog/


May 12, 2013 | 4 comments

DDD: Questions around ubiquitous language

What happens in situations where the developers and the business don’t agree on the terminology — the Ubiquitous Language — of a system?

This post was inspired by a blog post by Greg Young, which was in turn inspired by a question on the DDD mailing list. Here are some of my experiences where this has occurred.

Developers propose a more precise name

Sometimes in conversations you will find different users speaking about the same concept, but using different words. Alternatively, they might use a common slang term, or short-hand abbreviation. As part of the vocabulary of your system (ubiquitous language), you should settle on a single name, unabbreviated, that is clear to everyone what it means (including new developers).

Here’s a very simple example of this, a new developer’s thought process when looking at a class in a market risk system:

  • Ticker — okay, probably some sort of ticker symbol. But I know different exchanges and data providers use their own proprietary symbols and notation, so I better not make any assumptions.
  • Bloomberg Ticker — ah. It is a symbol ticker that came from Bloomberg. I know where to look it up, and also that it’s not necessarily referring a stock traded on an exchange (it could be a country for example).

This is an improvement that clarifies the concept using the most formally correct — but maybe less commonly used — terminology.

As well, expanding abbreviations may be supported by programming language conventions — for example, in .NET, abbreviations are usually discouraged in favour of longer identifiers, expressed using full words.

Dev team proposes using a term that has never been used before

Generally, you should not ever need to do this. Introducing your own terminology can be confusing, and if it is a well-established business area, they will already have a well-established vocabulary.

The only situation I can think of, where it might be acceptable for the development team to propose that the business should use a different term for something, is when building out software for a brand new business area, where a firm vocabulary has not yet been established — For example, in a software startup still figuring out their business model.

If you do go this route, you must ensure the new term has to be agreed by everyone (developers, UX people, and the business) before you start adopting it. And keep an eye/ear out — if people still keep using the old term, cut your losses and revert to the old term in your code too.

Product Owner says, “let’s just rename the label on screen”

The third situation where implications may be unclear is when a product owner drops you a quick note, asking you to please change the name of a field in the UI. Technically, this is a quick change, but does this mean the ubiquitous language has changed, we should rename it all through the code as well?

This is a situation I’ve certainly encountered more than once, and more often than not, it comes from a cost/schedule/risk background. Read between the lines — what is the Product Owner considering when he or she makes this request?

  • Renaming a field in the UI: a small that should be quick to implement, without much risk of breaking anything.
  • Renaming a field all the way down to persistent storage (e.g. database tables): this is a much bigger change that will require a lot more time (more $$$), may impact the schedule, and could cause many things to break.

Use your judgement here. Is this really just renaming a field on screen, or has the vocabulary of the business changed?

If you think you can rename all through the code/database quickly, and have good unit/integration test coverage to prove everything still works, you might as well do it. But if you think it will take longer, the most pragmatic thing would be to perform the UI label change as requested, but keep an eye/ear on the users to see whether the ubiquitous language really has changed.

If you don’t pay attention after, you run the risk of your code diverging from reality:

diverging_vocab_technical_debt

Changing terms in APIs and wire protocols

Another question is what to do in the case the term that is changing is part of an API signature or wire protocol, which you can’t change because it will break compatibility with other systems. I don’t think this is such a big concern, to leave the old name here:

  • This is only one place, at the very boundary of your system, with an inconsistent name.
  • APIs are typically well documented, including explanations, background and “gotchas” about every field. (Example here from the Twitter API).
  • In future versions of the API you will have a chance to rename it. Or, if accepting flexible formats like JSON, you can accept both forms (under the robustness principle).

February 16, 2013 |
Leave your comment