All posts by Gigi

Abstracting RabbitMQ RPC with TaskCompletionSource

I recently wrote about TaskCompletionSource, a little-known tool in .NET that is great for transforming arbitrary asynchrony into the Task-Based Asynchronous Pattern. That means you can hide the whole thing behind a simple and elegant async/await.

In this article, we’ll see this in practice as we implement the Remote Procedure Call (RPC) pattern in RabbitMQ. This is a fancy way of saying request/response, except that it all happens asynchronously! That’s right. No blocking.

The source code for this article is in the RabbitMqRpc folder at the Gigi Labs BitBucket Repository.

The RabbitMQ.Client NuGet package is necessary to make this code work. The client is written using an asynchronous Main() method, which requires at least C# 7.1 to compile.

RabbitMQ RPC Overview

You can think of RPC as request/response communication. We have a client asking a server to process some input and return the output in its response. However, this all happens asynchronously. The client sends the request on a request queue and forgets about it, rather than waiting for the response. Eventually, the server will (hopefully) process the request and send a response message back on a response queue.

The request and response can be matched on the client side by attaching a CorellationId to both the request and the response.

In this context, we don’t really talk about publishers and consumers, as is typical when talking about messaging frameworks. That’s because in order to make this work, both the client and the server must have both a publisher and a consumer.

Client: Main Program

For our client application, we’ll have the following main program code. We will implement an RpcClient that will hide the request/response plumbing behind a simple Task that we then await:

        static async Task Main(string[] args)
        {
            Console.Title = "RabbitMQ RPC Client";

            using (var rpcClient = new RpcClient())
            {
                Console.WriteLine("Press ENTER or Ctrl+C to exit.");

                while (true)
                {
                    string message = null;

                    Console.Write("Enter a message to send: ");
                    using (var colour = new ScopedConsoleColour(ConsoleColor.Blue))
                        message = Console.ReadLine();

                    if (string.IsNullOrWhiteSpace(message))
                        break;
                    else
                    {
                        var response = await rpcClient.SendAsync(message);

                        Console.Write("Response was: ");
                        using (var colour = new ScopedConsoleColour(ConsoleColor.Green))
                            Console.WriteLine(response);
                    }
                }
            }
        }

The program continuously asks for input, and sends that input as the request message. The server will process this message and return a response. Note that we are using the ScopedConsoleColour class from my “Scope Bound Resource Management in C#” article to colour certain sections of the output. Here is a taste of what it will look like:

While this console application only allows us to send one request at a time, the underlying approach is really powerful with APIs that can concurrently serve a multitude of clients. It is asynchronous and can scale pretty well, yet the consuming code sees none of the underlying complexity.

Client: Request Sending

The heart of this abstraction is the RpcClient class. In the constructor, we set up the typical plumbing: create a connection, channel, queues, and a consumer.

    public class RpcClient : IDisposable
    {
        private bool disposed = false;
        private IConnection connection;
        private IModel channel;
        private EventingBasicConsumer consumer;
        private ConcurrentDictionary<string,
            TaskCompletionSource<string>> pendingMessages;

        private const string requestQueueName = "requestqueue";
        private const string responseQueueName = "responsequeue";
        private const string exchangeName = ""; // default exchange

        public RpcClient()
        {
            var factory = new ConnectionFactory() { HostName = "localhost" };

            this.connection = factory.CreateConnection();
            this.channel = connection.CreateModel();

            this.channel.QueueDeclare(requestQueueName, true, false, false, null);
            this.channel.QueueDeclare(responseQueueName, true, false, false, null);

            this.consumer = new EventingBasicConsumer(this.channel);
            this.consumer.Received += Consumer_Received;
            this.channel.BasicConsume(responseQueueName, true, consumer);

            this.pendingMessages = new ConcurrentDictionary<string,
                TaskCompletionSource<string>>();
        }

        // ...
    }

A few other things to notice here:

  1. We are keeping a dictionary that allow us to match responses with the requests that generated them, based on a CorrelationId. We have already seen this approach in “TaskCompletionSource by Example“.
  2. This class implements IDisposable, as it has several resources that need to be cleaned up. While I don’t show the code for this for brevity’s sake, you can find it in the source code.
  3. We are not using exchanges here, so using an empty string for the exchange name allows us to use the default exchange and publish directly to the queue.

The SendAsync() method, which we saw being used in the main program, is implemented as follows:

        public Task<string> SendAsync(string message)
        {
            var tcs = new TaskCompletionSource<string>();
            var correlationId = Guid.NewGuid().ToString();

            this.pendingMessages[correlationId] = tcs;

            this.Publish(message, correlationId);

            return tcs.Task;
        }

Here, we are generating GUID to use as a CorrelationId, and we are adding an entry in the dictionary for this request. This dictionary maps the CorrelationId to a corresponding TaskCompletionSource. When the response arrives, it will set the result on this TaskCompletionSource, which enables the underlying task to complete. We return this underlying task, and that’s what the main program awaits. The main program will not be able to continue until the response is received.

In this method, we are also calling a private Publish() method, which takes care of the details of publishing to the request queue on RabbitMQ:

        private void Publish(string message, string correlationId)
        {
            var props = this.channel.CreateBasicProperties();
            props.CorrelationId = correlationId;
            props.ReplyTo = responseQueueName;

            byte[] messageBytes = Encoding.UTF8.GetBytes(message);
            this.channel.BasicPublish(exchangeName, requestQueueName, props, messageBytes);

            using (var colour = new ScopedConsoleColour(ConsoleColor.Yellow))
                Console.WriteLine($"Sent: {message} with CorrelationId {correlationId}");
        }

While this publishing code is for the most part pretty standard, we are using two particular properties that are especially suited for the RPC pattern. The first is CorrelationId, where we store the CorrelationId we generated earlier, and which the server will copy and send back as part of the response, enabling this whole orchestration. The second is the ReplyTo property, which is used to indicate to the server on which queue it should send the response. We don’t need it for this simple example since we are always using the same response queue, but this property enables the server to dynamically route responses where they are needed.

Server

The request eventually reaches a server which has a consumer waiting on the request queue. Its Main() method is mostly plumbing that enables this consumer to work:

        private static IModel channel;

        static void Main(string[] args)
        {
            Console.Title = "RabbitMQ RPC Server";

            var factory = new ConnectionFactory() { HostName = "localhost" };

            using (var connection = factory.CreateConnection())
            {
                using (channel = connection.CreateModel())
                {
                    const string requestQueueName = "requestqueue";
                    channel.QueueDeclare(requestQueueName, true, false, false, null);

                    // consumer

                    var consumer = new EventingBasicConsumer(channel);
                    consumer.Received += Consumer_Received;
                    channel.BasicConsume(requestQueueName, true, consumer);

                    Console.WriteLine("Waiting for messages...");
                    Console.WriteLine("Press ENTER to exit.");
                    Console.WriteLine();
                    Console.ReadLine();
                }
            }
        }

When a message is received, the Consumer_Received event handler processes the message:

        private static void Consumer_Received(object sender, BasicDeliverEventArgs e)
        {
            var requestMessage = Encoding.UTF8.GetString(e.Body);
            var correlationId = e.BasicProperties.CorrelationId;
            string responseQueueName = e.BasicProperties.ReplyTo;

            Console.WriteLine($"Received: {requestMessage} with CorrelationId {correlationId}");

            var responseMessage = Reverse(requestMessage);
            Publish(responseMessage, correlationId, responseQueueName);
        }

In this example, the server’s job is to reverse whatever messages it receives. Thus, each response will contain the same message as in the corresponding request, but backwards. This reversal code is taken from this Stack Overflow answer. Although trivial to implement, this serves as a reminder that there’s no need to reinvent the wheel if somebody already implemented the same thing (and quite well, at that) before you.

        public static string Reverse(string s)
        {
            char[] charArray = s.ToCharArray();
            Array.Reverse(charArray);
            return new string(charArray);
        }

Having computed the reverse of the request message, and extracted both the CorrelationId and ReplyTo properties, these are all passed to the Publish() method which sends back the response:

        private static void Publish(string responseMessage, string correlationId,
            string responseQueueName)
        {
            byte[] responseMessageBytes = Encoding.UTF8.GetBytes(responseMessage);

            const string exchangeName = ""; // default exchange
            var responseProps = channel.CreateBasicProperties();
            responseProps.CorrelationId = correlationId;

            channel.BasicPublish(exchangeName, responseQueueName, responseProps, responseMessageBytes);

            Console.WriteLine($"Sent: {responseMessage} with CorrelationId {correlationId}");
            Console.WriteLine();
        }

The response is sent back on the queue specified in the ReplyTo property of the request message. The response is also given the same CorrelationId as the request; that way the client will know that this response is for that particular request.

Client: Response Handling

When the response arrives, the client’s own consumer event handler will run to process it:

        private void Consumer_Received(object sender, BasicDeliverEventArgs e)
        {
            var correlationId = e.BasicProperties.CorrelationId;
            var message = Encoding.UTF8.GetString(e.Body);

            using (var colour = new ScopedConsoleColour(ConsoleColor.Yellow))
                Console.WriteLine($"Received: {message} with CorrelationId {correlationId}");

            this.pendingMessages.TryRemove(correlationId, out var tcs);
            if (tcs != null)
                tcs.SetResult(message);
        }

The client extracts the CorrelationId from the response, and uses it to get the TaskCompletionSource for the corresponding request. If the TaskCompletionSource is found, then its result is set to the content of the response. This causes the underlying task to complete, and thus the caller awaiting that task will be able to resume and work with the result.

If the TaskCompletionSource is not found, then we ignore the response, and there is a reason for this:

“You may ask, why should we ignore unknown messages in the callback queue, rather than failing with an error? It’s due to a possibility of a race condition on the server side. Although unlikely, it is possible that the RPC server will die just after sending us the answer, but before sending an acknowledgment message for the request. If that happens, the restarted RPC server will process the request again. That’s why on the client we must handle the duplicate responses gracefully, and the RPC should ideally be idempotent.” — RabbitMQ RPC tutorial

Demo

If we run both the client and server, we can enter messages in the client, one by one. The client publishes each message on the request queue and waits for the response, at which point it allows the main program to continue by setting the result of that request’s TaskCompletionSource.

Summary

What we have seen in this article is the same material I had explained in “TaskCompletionSource by Example“, but with a real application to RabbitMQ.

A TaskCompletionSource has an underlying Task that can represent a pending request. By giving each request an ID, you can keep track of it as the corresponding response should carry the same ID. A mapping between request IDs and TaskCompletionSource can easily be kept in a dictionary. When a response arrives, its corresponding entry in the dictionary can be found, and the Task can be completed. Any client code awaiting this Task may then resume.

SignalR Core: Hello World

SignalR is a library that brought push notifications to ASP .NET web applications. It abstracted away the complexity of dealing with websockets and other front-end technologies necessary for a web application to spontaneously push out updates to client applications, and provided an easy programming model.

Essentially, SignalR allows us to implement publish/subscribe on the server. Clients, which are typically (but not necessarily) webpages, subscribe to a hub, which can then push updates to them. These updates can be sent spontaneously by the server (e.g. stock ticker) or triggered by a message from a client (e.g. chat).

The old SignalR, however, is not compatible with ASP .NET Core. So if you wanted to have push notifications in your web application, you had to look elsewhere… until recently. Microsoft shipped their first alpha release of SignalR Core (SignalR for ASP .NET Core 2.0) a few weeks ago, and the second alpha was released just yesterday. They also have some really nice samples we can learn from.

This article explains how to quickly get started with SignalR Core, by means of a simple Hello World application that combines a simple server-side hub with a trivial JavaScript client. It is essentially the first example from my “Getting Started with SignalR“, ported to SignalR Core.

The source code for this article is in the SignalRCoreHello folder at the Gigi Labs BitBucket Repository.

Hello SignalR Core: Server Side

This example is based on SignalR Core alpha 2, and uses ASP .NET Core 2 targeting .NET Core 2. As this is pre-release software, APIs may change.

Let’s start off by creating a new ASP .NET Core Web Application in Visual Studio 2017. We can start off simple by using the Empty project template:

This project template should come with a reference to the Microsoft.AspNet.All NuGet package, giving you most of what you need to create our web application.

In addition to that, we’ll need to install the NuGet package for SignalR. Note that we need the -Pre switch for now because it is still prerelease.

Install-Package Microsoft.AspNetCore.SignalR -Pre

Next, let’s add a Hub. Just add a new class:

    public class HelloHub : Hub
    {
        public Task BroadcastHello()
        {
            return Clients.All.InvokeAsync("hello");
        }
    }

In SignalR Core, a class that inherits from Hub is able to communicate with any clients that are subscribed to it. This can be done in several ways: broadcast to all clients or all except one; send to a single client; or send to a specific group. In this case, we’re simply broadcasting a “hello” message to all clients.

In the Startup class, we need to remove the default “Hello world” code and register our Hub instead. It should look something like this:

    public class Startup
    {
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddSignalR();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseFileServer();

            app.UseSignalR(routes =>
            {
                routes.MapHub<HelloHub>("hello");
            });
        }
    }

UseSignalR() is where we register the route by which our Hub will be accessed from the client side. UseFileServer() is there just to serve the upcoming HTML and JavaScript.

Hello SignalR Core: Client Side

In order to have a webpage that talks to our Hub, we first need a couple of scripts. We’ll get these using npm, which you can obtain by installing Node.js if you don’t have it already.

npm install @aspnet/signalr-client
npm install jquery

The first package is the client JavaScript for SignalR Core. At the time of writing this article, the file you need is called signalr-client-1.0.0-alpha2-final.js. The second package is jQuery, which is no longer required by SignalR Core, but will make life easier for our front-end code. Copy both signalr-client-1.0.0-alpha2-final.js and jquery.js into the wwwroot folder.

Next, add an index.html file in the wwwroot folder. Add references to the aforementioned scripts, a placeholder for messages (with ID “log” in this example), and a little script to wire things up:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Hello SignalR Core!</title>
    <script src="jquery.js"></script>
    <script src="signalr-client-1.0.0-alpha2-final.js"></script>
    <script type="text/javascript">
            $(document).ready(function () {
                var connection = new signalR.HubConnection('/hello');

                connection.on('hello', data => {
                    $("#log").append("Hello <br />");
                });

                connection.start()
                    .then(() => connection.invoke('BroadcastHello'));
            });
    </script>
</head>
<body>
    <div id="log"></div>
</body>
</html>

This JavaScript establishes a connection to the hub, registers a callback for when a “hello” message is received, and calls the BroadcastHello() method on the hub:

The way we implemented our Hub earlier, it will send a “hello” message to all connected clients.

Let’s give that a try now:

Good! The connection is established, and we’re getting something back from the server (i.e. the Hub). Let’s open a couple more browser windows at the same endpoint:

Here, we can see that each time a new window was opened, a new “hello” message was broadcasted to all connected clients. Since we are not holding any state, messages are sent incrementally, so newer clients that missed earlier messages will be showing fewer messages.

The Chat Sample

If you want to see a more elaborate example, check out the Chat sample from the official SignalR Core samples:

The principle is the same, but the Chat sample is a little more interesting.

Adding Swagger to an ASP .NET Core 2 Web API

If you develop REST APIs, then you have probably heard of Swagger before.

Swagger is a tool that automatically documents your Web API, and provides the means to easily interact with it via an auto-generated UI.

In this article, we’ll see how to add Swagger to an ASP .NET Core Web API. We’ll be using the .NET Core 2 SDK, so if you’re using an earlier version, your mileage may vary. We’re only covering basic setup, so check out ASP.NET Web API Help Pages using Swagger in the Microsoft documentation if you want to go beyond that.

Project Setup

To make things easy, we’ll use one of the templates straight out of Visual Studio to get started. Go to File -> New -> Project… and select the ASP .NET Core Web Application template:

Next, pick the Web API template. You may want to change the second dropdown to ASP .NET Core 2.0, as it is currently not set to that by default.

Adding Swagger

You should now have a simple Web API project template with a ValuesController, providing an easy way to play with Web API out of the box.

To add Swagger, we first need to add a package:

Install-Package Swashbuckle.AspNetCore

Then, we throw in some configuration in Startup.cs to make Swagger work. Replace “My API” with whatever your API is called.

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();

            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new Info { Title = "My API", Version = "v1" });
            });
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseSwagger();

            app.UseSwaggerUI(c =>
            {
                c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
            });

            app.UseMvc();
        }

Note: if you’re starting with a more minimal project template, it is possible that you may need to install the Microsoft.AspNetCore.StaticFiles package for this to work. This package is already present in the project template we’re using above.

Accessing Swagger

Let’s now run the web application. We should see a basic JSON response from the ValuesController:

If we now change the URL to http://localhost:<port>/swagger/, then we get to the Swagger UI:

Here, we can see a list of all our controllers and their actions. We can also open them up to interact with them.

Summary

That’s all it takes to add Swagger to your ASP .NET Core Web API.

  1. Add the Swashbuckle.AspNetCore package.
  2. Configure Swagger in the startup class.
  3. Access Swagger from http://localhost:<port>/swagger/.

TaskCompletionSource by Example

In this article, we’ll learn how to use TaskCompletionSource. It’s one of those tools which you will rarely need to use, but when you do, you’ll be glad that you knew about it. Let’s dive right into it.

Basic Usage

The source code for this section is in the TaskCompletionSource1 folder at the Gigi Labs BitBucket Repository.

Let’s create a new console application, and in Main(), we’ll have my usual workaround for running asynchronous code in a console application:

        static void Main(string[] args)
        {
            Run();
            Console.ReadLine();
        }

In the Run() method, we have a simple example showing how TaskCompletionSource works:

        static async void Run()
        {
            var tcs = new TaskCompletionSource<bool>();

            var fireAndForgetTask = Task.Delay(5000)
                                        .ContinueWith(task => tcs.SetResult(true));

            await tcs.Task;
        }

TaskCompletionSource is just a wrapper for a Task, giving you control over its completion. Thus, a TaskCompletionSource<bool> will contain a Task<bool>, and you can set the bool result based on your own logic.

Here, we are using TaskCompletionSource as a synchronization mechanism. Our main thread spawns off an operation and waits for its result, using the Task in the TaskCompletionSource. Even if the operation is not Task-based, it can set the result of the Task in the TaskCompletionSource, allowing the main thread to resume its execution.

Let’s add some diagnostic code so that we can understand what’s going on from the output:

        static async void Run()
        {
            var stopwatch = Stopwatch.StartNew();

            var tcs = new TaskCompletionSource<bool>();

            Console.WriteLine($"Starting... (after {stopwatch.ElapsedMilliseconds}ms)");

            var fireAndForgetTask = Task.Delay(5000)
                                        .ContinueWith(task => tcs.SetResult(true));

            Console.WriteLine($"Waiting...  (after {stopwatch.ElapsedMilliseconds}ms)");

            await tcs.Task;

            Console.WriteLine($"Done.       (after {stopwatch.ElapsedMilliseconds}ms)");

            stopwatch.Stop();
        }

And here is the output:

Starting... (after 0ms)
Waiting...  (after 41ms)
Done.       (after 5072ms)

As you can see, the main thread waited until tcs.SetResult(true) was called; this triggered completion of the TaskCompletionSource’s underlying task (which the main thread was awaiting), and allowed the main thread to resume.

Aside from SetResult(), TaskCompletionSource offers methods to cancel a task or fault it with an exception. There are also safe Try...() equivalents:

SDK Example

The source code for this section is in the TaskCompletionSource2 folder at the Gigi Labs BitBucket Repository.

One scenario where I found TaskCompletionSource to be extremely well-suited is when you are given a third-party SDK which exposes events. Imagine this: you submit an order via an SDK method, and it gives you an ID for that order, but not the result. The SDK goes off and does what it has to do to perhaps talk to an external service and have the order processed. When this eventually happens, the SDK fires an event to notify the calling application on whether the order was placed successfully.

We’ll use this as an example of the SDK code:

    public class MockSdk
    {
        public event EventHandler<OrderOutcome> OnOrderCompleted;

        public Guid SubmitOrder(decimal price)
        {
            var orderId = Guid.NewGuid();

            // do a REST call over the network or something
            Task.Delay(3000).ContinueWith(task => OnOrderCompleted(this,
                new OrderOutcome(orderId, true)));

            return orderId;
        }
    }

The OrderOutcome class is just a simple DTO:

    public class OrderOutcome
    {
        public Guid OrderId { get; set; }
        public bool Success { get; set; }

        public OrderOutcome(Guid orderId, bool success)
        {
            this.OrderId = orderId;
            this.Success = success;
        }
    }

Notice how MockSdk‘s SubmitOrder does not return any form of Task, and we can’t await it. This doesn’t necessarily mean that it’s blocking; it might be using another form of asynchrony such as the Asynchronous Programming Model or a messaging framework with a request-response fashion (such as RPC over RabbitMQ).

At the end of the day, this is still asynchrony, and we can use TaskCompletionSource to build a Task-based Asynchronous Pattern abstraction over it (allowing the application to simply await the call).

First, we start building a simple proxy class that wraps the SDK:

    public class SdkProxy
    {
        private MockSdk sdk;

        public SdkProxy()
        {
            this.sdk = new MockSdk();
            this.sdk.OnOrderCompleted += Sdk_OnOrderCompleted;
        }

        private void Sdk_OnOrderCompleted(object sender, OrderOutcome e)
        {
            // TODO
        }
    }

We then add a dictionary, which allows us to relate each OrderId to its corresponding TaskCompletionSource. Using a ConcurrentDictionary instead of a normal Dictionary helps deal with multithreading scenarios without needing to lock:

        private ConcurrentDictionary<Guid,
            TaskCompletionSource<bool>> pendingOrders;
        private MockSdk sdk;

        public SdkProxy()
        {
            this.pendingOrders = new ConcurrentDictionary<Guid,
                TaskCompletionSource<bool>>();

            this.sdk = new MockSdk();
            this.sdk.OnOrderCompleted += Sdk_OnOrderCompleted;
        }

The proxy class exposes a SubmitOrderAsync() method:

        public Task SubmitOrderAsync(decimal price)
        {
            var orderId = sdk.SubmitOrder(price);

            Console.WriteLine($"OrderId {orderId} submitted with price {price}");

            var tcs = new TaskCompletionSource<bool>();
            this.pendingOrders.TryAdd(orderId, tcs);

            return tcs.Task;
        }

This method calls the underlying SubmitOrder() in the SDK, and uses the returned OrderId to add a new TaskCompletionSource in the dictionary. The TaskCompletionSource’s underlying Task is returned, so that the application can await it.

        private void Sdk_OnOrderCompleted(object sender, OrderOutcome e)
        {
            string successStr = e.Success ? "was successful" : "failed";
            Console.WriteLine($"OrderId {e.OrderId} {successStr}");

            this.pendingOrders.TryRemove(e.OrderId, out var tcs);
            tcs.SetResult(e.Success);
        }

When the SDK fires a completion event, the proxy will remove the TaskCompletionSource from the pending order and set its result. The application awaiting the underlying task will resume and take a decision depending on the logic.

We can test this with the following program code in a console application:

        static void Main(string[] args)
        {
            Run();
            Console.ReadLine();
        }

        static async void Run()
        {
            var sdkProxy = new SdkProxy();

            await sdkProxy.SubmitOrderAsync(10);
            await sdkProxy.SubmitOrderAsync(20);
            await sdkProxy.SubmitOrderAsync(5);
            await sdkProxy.SubmitOrderAsync(15);
            await sdkProxy.SubmitOrderAsync(4);
        }

The output shows that the program did indeed wait for each order to complete before starting the next one:

OrderId 3e2d4577-8bbb-46b7-a5df-2efec23bae6b submitted with price 10
OrderId 3e2d4577-8bbb-46b7-a5df-2efec23bae6b was successful
OrderId e22425b9-3aa3-48db-a40f-8b8cfbdcd3af submitted with price 20
OrderId e22425b9-3aa3-48db-a40f-8b8cfbdcd3af was successful
OrderId 3b5a2602-a5d2-4225-bbdb-10642a63f7bc submitted with price 5
OrderId 3b5a2602-a5d2-4225-bbdb-10642a63f7bc was successful
OrderId ffd61cea-343e-4a9c-a76f-889598a45993 submitted with price 15
OrderId ffd61cea-343e-4a9c-a76f-889598a45993 was successful
OrderId b443462c-f949-49b9-a6f0-08bbbb82fe7e submitted with price 4
OrderId b443462c-f949-49b9-a6f0-08bbbb82fe7e was successful

Summary

Use TaskCompletionSource to adapt an arbitrary form of asynchrony to use Tasks, and enable elegant async/await usage.

Do not use it simply expose an asynchronous wrapper for a synchronous method. You should either not do that at all, or use Task.FromResult() instead.

If you’re concerned that the the asynchronous call might never resume, consider adding a timeout.

Common Mistakes in Asynchronous Programming with .NET

In the last few articles, we have seen how to work with asynchronous programming in C#. Although it is now easier than ever to write responsive applications that do asynchronous, non-blocking I/O operations, many people still use asynchronous programming incorrectly. A lot of this is due to confusion over usage of the Task class in .NET, which is used in multithreaded and parallel scenarios as well as asynchronous ones. To make matters worse, it is not obvious to everyone that these are actually different things.

So let’s address this concern first.

Update 16th October 2017: Several people have pointed out errors in this article with regards to the effect that blocking has on the CPU. I apologise for this, and have made corrections. Blocking does not hog the CPU, but prevents threads from doing other work while they wait. Thanks for clarifying the confusion, and I welcome any further corrections.

Asynchronous vs Multithreading etc

When we use a computer, many programs are running at the same time. Before the advent of multicore CPUs, this was achieved by having instructions from different processes (and eventually threads) running one at a time on the same CPU. These instructions are interleaved, and the CPU switches rapidly from one to another (in what we call a context switch), giving the illusion that they are running at the same time. This is concurrency.

CPUs with multiple cores have the additional ability of literally executing multiple intructions at the same time, which is parallel execution. Multithreading gives the developers to make full use of the available cores; without it, instructions from a single process would only be able to execute on a single core at a time.

“Tasks which are executing on distinct processors at any point in time are said to be running in parallel. It may also be possible to execute several tasks on a single processor. Over a period of time, the impression is given that they are running in parallel, when in fact, at any point in time, only one task has control of the processor. In this case, we say that the tasks are being performed concurrently, that is, their execution is being shared by the same processor.” — Practical Parallel Rendering, Chalmers et al, A K Peters, 2002.

In .NET, we can do parallel processing by using multithreading, or an abstraction thereof, such as the Task Parallel Library. Parallel processing is CPU-bound.

Parallel processing is often contrasted with distributed processing, where the computing resources are not physically tightly coupled. This is not, however, relevant to asynchronous programming, so we will not delve into it.

Operations that take a long time to execute will typically hold control of the thread in which they are running, in what we call a blocking operation. However, if these operations involve waiting for I/O to occur (e.g. waiting for results from a file, network or database), then the I/O could occur in a non-blocking fashion without holding the thread at all during the waiting time. We say that the I/O operation is asynchronous: the thread that is waiting for it does not actually wait, but may be reassigned to do other work until the I/O operation is complete.

Asynchronous non-blocking I/O is not enabled by multithreading. In fact, Stephen Cleary goes into detail about how this works in his excellent post, “There Is No Thread“. In brief, a mechanism known as I/O Completion Ports (IOCP) is used to notify a thread that its I/O request is ready; but that thread does not need to block (or indeed run at all) during the waiting time. This is what we enable when we do an asynchronous wait by means of the await keyword.

In order to write efficient code, it is fundamental to understand the nature of what the code is doing. Parallel CPU-based execution involves significant overheads in thread synchronization. It makes no sense to use Parallel.ForEach() for I/O-bound tasks, and many are also surprised to find that executing CPU-based tasks sequentially is often faster than doing them in parallel, especially when such tasks are fine-grained and do very trivial work. In such cases, the synchronization overheads dwarf the cost of executing that code directly on the CPU on a single thread.

See also: “Asynchronous and Concurrent Processing in Akka .NET Actors“, which has a section on Asynchronous vs Concurrent Processing using simple tasks.

The Dangers of Blocking with Asynchronous Code

Asynchronous programming has two main benefits: scalability and offloading. If you block, then you are hogging resources (i.e. threads) that could be better used elsewhere. In an ASP .NET context, this means that a thread cannot service other requests (hurts scalability). In a GUI context, it means that the UI thread cannot be used for rendering because it is busy waiting for a long-running operation (so the work should be offloaded).

There are several methods which are part of the Task API which block, such as Wait(), WaitAny() and WaitAll(). The Result property also has the effect of blocking until the task is complete. Stephen Cleary has a table in his Async and Await intro showing these blocking API calls and how to turn them into asynchronous calls. Best practice is to await the asynchronous equivalent of the blocking method

However, simply wasting threading resources is not the only problem with blocking. It is actually very easy to end up with a deadlock and stall your application. Stephen Cleary has an excellent explanation of how this happens, with two concise examples based on GUI applications (e.g. WPF or Windows Forms) and ASP .NET. I am only going to attempt to simplify the scenario and illustrate it with a diagram.

Consider the following code in a WPF application’s codebehind (MainWindow.xaml.cs):

        private Uri uri = new Uri("http://ip.jsontest.com/");

        public async Task WaitABit()
        {
            await Task.Delay(3000);
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            var task = WaitABit();
            task.Wait();
        }

This results in deadlock. Let’s see why:

  1. Button_Click() calls WaitABit() without awaiting it. This starts a task in fire-and-forget mode (so far).
  2. WaitABit() calls Task.Delay() and awaits its result asynchronously. The thread does not block, since the execution has gone into “I/O mode” (technically a delay isn’t really I/O, but the idea is the same).
  3. In the meantime, Button_Click() resumes execution, and calls Wait(), effectively blocking until the result of WaitABit() is ready.
  4. The delay completes.
  5. WaitABit() should resume, but the UI thread that it’s supposed to run on is already blocked.
  6. The deadlock occurs because the continuation of WaitABit() needs to run on the UI thread, but the UI thread is blocked waiting for the result of WaitABit().

Note: I intentionally haven’t simplified WaitABit() such that it just returns the delay rather than doing a single-line async/await, as it would not deadlock. Can you guess why?

This example has shown blocking of the UI thread, but the concept stretches beyond GUI applications. In order to fully understand what is happening, we need to understand what a SynchronizationContext is. In short, it’s an abstraction of a threading model within an application. A GUI application needs a single UI thread for rendering and updating GUI components (although you can use other threads, they cannot touch the GUI directly). An ASP .NET application, on the other hand, handles requests using the thread pool. The SynchronizationContext is the abstraction that allows us to use the same multithreaded and asynchronous programming models across applications with fundamentally different internal threading models.

As a result, GUI applications (e.g. Windows Forms and WPF) and ASP .NET applications (those targeting the full .NET Framework) can deadlock. ASP .NET Core applications don’t have a SynchronizationContext, so they will not deadlock. Console applications won’t normally deadlock because the task continuation can just execute on another thread.

The deadlock occurs because the SynchronizationContext (e.g. the UI thread in the above example) is captured and used for the task continuation. However, we can prevent this from happening by using ConfigureAwait(false):

        public async Task WaitABit()
        {
            await Task.Delay(3000).ConfigureAwait(false);
        }

The GUI application does not deadlock now, because a thread pool can be picked to execute the continuation. Once WaitABit() completes, then the blocking Wait() in Button_Click() can resume on the same UI thread where it started. Any modifications to UI elements would work fine.

While ConfigureAwait(false) is no replacement for doing async/await all the way, it does have its benefits. Capturing the SynchronizationContext incurs a performance penalty, so if it is not actually necessary, library code should avoid it by using ConfigureAwait(false). Also, if application code must block on an asynchronous call for legacy reasons, then ConfigureAwait(false) would avoid the resulting deadlocks.

Of course, the real fix for our deadlock example here is really as easy as this (without ConfigureAwait(false)):

        private async void Button_Click(object sender, RoutedEventArgs e)
        {
            var task = WaitABit();
            await task;
        }

I’ve just replaced the blocking Wait() call with an await, and marked the method as async as a result.

Asynchronous Wrappers for Synchronous Methods

A lot of library APIs with asynchronous methods have pairs of synchronous and asynchronous methods, e.g. Read() and ReadAsync(), Write() and WriteAsync(), etc. If your library API is purely synchronous, then you should not expose asynchronous wrappers for the synchronous methods (e.g. by using Task.Run()).

Stephen Toub goes into detail on why this is a bad idea in the article linked above, but I think the following paragraph summarises it best:

“If a developer needs to achieve better scalability, they can use any async APIs exposed, and they don’t have to pay additional overhead for invoking a faux async API. If a developer needs to achieve responsiveness or parallelism with synchronous APIs, they can simply wrap the invocation with a method like Task.Run.” — Stephen Toub, “Should I expose asynchronous wrappers for synchronous methods?

Asynchronous Properties

You can’t use async/await in properties. You can use them indirectly via an asynchronous method, but it’s a rather weird thing to do.

“[You can’t use await i]nside of a property getter or setter. Properties are meant to return to the caller quickly, and thus are not expected to need asynchrony, which is geared for potentially long-running operations. If you must use asynchrony in your properties, you can do so by implementing an async method which is then used from your property.” — Stephen Toub, Async/Await FAQ

async void methods

async void methods should only be used for top-level event handlers. In “The Dangers of async void Event Handlers“, I explain the general dangers of async void methods (mainly related to not having a task that you can await), but I also demonstrate and solve the additional problem of async void event handlers interleaving while they run (which is problematic if you’re expecting to handle events in sequence, such as with a message queue).

    1. “There is no way for the caller to await completion of the method.
    2. “As a result of this, async void calls are fire-and-forget.
    3. “Thus it follows that async void methods (including event handlers) will execute in parallel if called in a loop.
    4. “Exceptions can cause the application to crash (see the aforementioned article by Stephen Cleary for more on this).”

— Daniel D’Agostino, The Dangers of async void Event Handlers

Summary

  1. Parallel is CPU-based. Asynchronous is I/O-based. Don’t mix the two. (Running asynchronous I/O tasks “in parallel” is OK, as long as you’re doing it following the proper patterns rather than using something like Parallel.Foreach().)
  2. Asynchronous I/O does not use any threads.
  3. Blocking affects scalability and can hold higher-priority resources (such as a UI thread).
  4. Blocking can also result in deadlocks. Prevent them by using async/await all the way if you can. ConfigureAwait(false) is useful in library code both for performance reasons and to prevent deadlocks resulting from application code that must block for legacy reasons.
  5. For asynchronous libraries, don’t expose synchronous wrappers. There is an overhead associated with it, and the client can decide whether it’s worth doing from their end.
  6. You can’t have asynchronous properties, except indirectly via asynchronous methods. Avoid this.
  7. async void is for event handlers. Even so, if ordering is important, beware of interleaving.

Patterns for Asynchronous Composite Tasks in C#

In the previous two articles, I’ve explained why and how to use async/await for asynchronous programming in C#.

Now, we will turn our attention to more interesting things that we can do when combining multiple tasks within the same method.

Fast Food Example

In order to see each pattern at work, we need a simple example involving multiple tasks. Imagine you walk into your favourite fast food restaurant, and order a meal involving a burger, fries and a drink. Each of these takes a different amount of time to prepare, and the total time of the order may vary depending on how the execution of these three tasks takes place.

Sequential Tasks

The simplest approach is to just execute tasks one after another, waiting for one to finish before starting the next.

        static void Main(string[] args)
        {
            OrderAsync();
            Console.ReadLine();
        }

        static async void OrderAsync()
        {
            var stopwatch = Stopwatch.StartNew();

            await Task.Delay(3000)
                .ContinueWith(task => ShowCompletion("Fries", stopwatch.Elapsed));
            await Task.Delay(1000)
                .ContinueWith(task => ShowCompletion("Drink", stopwatch.Elapsed));
            await Task.Delay(5000)
                .ContinueWith(task => ShowCompletion("Burger", stopwatch.Elapsed));

            ShowCompletion("Order", stopwatch.Elapsed);

            stopwatch.Stop();
        }

        static void ShowCompletion(string name, TimeSpan time)
        {
            Console.WriteLine($"{name} completed after {time}");
        }

In this example code, we are representing the fries, drink and burger tasks as delays of different length. The rest of the code is purely diagnostic in order to allow us to get some output and understand the results. There is also a workaround allowing us to use asynchronous code in Main(), that was described in the previous article.

Here is the output from the above:

Fries completed after 00:00:03.0359621
Drink completed after 00:00:04.0408785
Burger completed after 00:00:09.0426927
Order completed after 00:00:09.0434057

Because we performed each task sequentially, the total order took 9 seconds. In a fast food restaurant, it probably does not make sense to wait for the fries to be ready before preparing the drink, and to wait for both to be ready before starting to prepare the burger. These could be done in parallel, as we will see in the next sections.

However, there are many legitimate cases where sequential task execution makes sense. We’ve seen one in “Motivation for async/await in C#“:

private async void Button_Click(object sender, RoutedEventArgs e)
{
    var baseAddress = new Uri("http://mta.com.mt");
 
    using (var httpClient = new HttpClient() { BaseAddress = baseAddress })
    {
        var response = await httpClient.GetAsync("/");
        var content = await response.Content.ReadAsStringAsync();
 
        MessageBox.Show("Response arrived!", "Slow website");
    }
}

In this case, the tasks are dependent on each other. In order to get the content of the response, the response itself must first finish executing. Because there is this dependency, the tasks must be executed one after the other.

Parallel Tasks, All Must Finish

If we fire off the tasks without awaiting them right away, there are more interesting things we can do with them. Essentially, by removing await, we are running the tasks in parallel.

        static async void OrderAsync()
        {
            var stopwatch = Stopwatch.StartNew();

            var friesTask = Task.Delay(3000)
                .ContinueWith(task => ShowCompletion("Fries", stopwatch.Elapsed));
            var drinkTask = Task.Delay(1000)
                .ContinueWith(task => ShowCompletion("Drink", stopwatch.Elapsed));
            var burgerTask = Task.Delay(5000)
                .ContinueWith(task => ShowCompletion("Burger", stopwatch.Elapsed));

            await Task.WhenAll(friesTask, drinkTask, burgerTask);

            ShowCompletion("Order", stopwatch.Elapsed);

            stopwatch.Stop();
        }

Aside from removing await before each task, we are assigning them to variables so that we can keep track of them. We then rely on Task.WhenAll() to wait until all tasks have completed (as an analogy, think of it as a memory barrier). Task.WhenAll() is awaitable, unlike its blocking cousin Task.WaitAll(). This gives us a way to easily run asynchronous tasks in parallel where it makes sense to do so.

And in a fast food restaurant, preparing fries and drink while the burger is cooking makes a lot of sense. In fact, the order is ready after just 5 seconds, which is the time of the longest task (the burger). Because the fries and drink were prepared concurrently with the burger, they did not add anything to the total time of the order.

Drink completed after 00:00:01.1696855
Fries completed after 00:00:03.0363008
Burger completed after 00:00:05.0443482
Order completed after 00:00:05.0445130

Note that Task.WhenAll() takes an IEnumerable<Task>, and as such, you can easily pass it a list of tasks (e.g. when the number of tasks is dynamic based on input or data).

Parallel Tasks, First To Finish

If you’re hungry and thirsty after an unexpected trip in the desert, it’s unlikely that you’re going to want to wait for all items to finish before starting to eat and drink. Instead, you’ll consume each item as soon as it arrives.

        static async void OrderAsync()
        {
            var stopwatch = Stopwatch.StartNew();

            var friesTask = Task.Delay(3000)
                .ContinueWith(task => ShowCompletion("Fries", stopwatch.Elapsed));
            var drinkTask = Task.Delay(1000)
                .ContinueWith(task => ShowCompletion("Drink", stopwatch.Elapsed));
            var burgerTask = Task.Delay(5000)
                .ContinueWith(task => ShowCompletion("Burger", stopwatch.Elapsed));

            await Task.WhenAny(friesTask, drinkTask, burgerTask);

            ShowCompletion("Order", stopwatch.Elapsed);

            stopwatch.Stop();
        }

Task.WhenAny() will wait until the first task has completed, and then resume execution of the method. It also returns the task that completed (though we’re not using that here).

Drink completed after 00:00:01.0390588
Order completed after 00:00:01.0412190
Fries completed after 00:00:01.0413729
Burger completed after 00:00:01.0413729

Our results are a little messed up. Since Task.WhenAny() only waits for the first task to complete, the entire order was considered complete as soon as the drink was ready. The stopwatch was subsequently stopped, and the output shows 1 second for everything even though the fries and burger actually took longer.

This scenario is useful when you want to retrieve data from different sources and just use the result that arrived fastest. It is not very intuitive for when you’re dying of hunger and want to gobble up everything as it arrives. We’ll address this in the next section.

Parallel Tasks, All Must Finish, Process As They Arrive

So here’s the scenario: we’re famished, and we want to consume our drink, fries and burger as they are ready. We want to consume all of them, but Task.WhenAny() only gives us the first task that completed.

It’s easy to reuse Task.WhenAny() to wait for all tasks to complete, by using a simple loop.

        static async void OrderAsync()
        {
            var stopwatch = Stopwatch.StartNew();

            var friesTask = Task.Delay(3000)
                .ContinueWith(task => ShowCompletion("Fries", stopwatch.Elapsed));
            var drinkTask = Task.Delay(1000)
                .ContinueWith(task => ShowCompletion("Drink", stopwatch.Elapsed));
            var burgerTask = Task.Delay(5000)
                .ContinueWith(task => ShowCompletion("Burger", stopwatch.Elapsed));

            var tasks = new List<Task>() { friesTask, drinkTask, burgerTask };
            
            while (tasks.Count > 0)
            {
                var task = await Task.WhenAny(tasks);
                tasks.Remove(task);

                Console.WriteLine($"Yum! {tasks.Count} left!");
            }

            ShowCompletion("Order", stopwatch.Elapsed);

            stopwatch.Stop();
        }

We’re putting all tasks in a list, and as each task completes, we remove it from the list. We know we’re done when there’s nothing left in the list.

Drink completed after 00:00:01.0506610
Yum! 2 left!
Fries completed after 00:00:03.0328112
Yum! 1 left!
Burger completed after 00:00:05.0317576
Yum! 0 left!
Order completed after 00:00:05.0331167

From this example, it might appear that there’s no benefit from using this approach when compared to just using continuations on tasks and using Task.WhenAll(). However, in real scenarios that don’t involve french fries, it is often reasonable to check the result of each task for failure. If one of the tasks fails, then the operation is aborted without having to wait for all the other tasks to complete.

Task With Timeout

As it turns out, we’re so hungry that we’re only willing to wait up to 4 seconds for each item, since the start of the order. If they take longer than 4 seconds, we’ll cancel that part of the order.

Fortunately, there’s an excellent blog post on the Parallel Programming MSDN blog from 2011 that shows how to write a TimeoutAfter() method that does exactly this. I’ll go ahead and steal it:

    public static class TaskExtensions
    {
        public static async Task TimeoutAfter(this Task task, int millisecondsTimeout)
        {
            if (task == await Task.WhenAny(task, Task.Delay(millisecondsTimeout)))
                await task;
            else
                throw new TimeoutException();
        }
    }

It’s an extension method, so we can easily use it with the tasks we already have:

        static async void OrderAsync()
        {
            var stopwatch = Stopwatch.StartNew();

            var friesTask = Task.Delay(3000).TimeoutAfter(4000)
                .ContinueWith(task => ShowCompletion("Fries", stopwatch.Elapsed));
            var drinkTask = Task.Delay(1000).TimeoutAfter(4000)
                .ContinueWith(task => ShowCompletion("Drink", stopwatch.Elapsed));
            var burgerTask = Task.Delay(5000).TimeoutAfter(4000)
                .ContinueWith(task => ShowCompletion("Burger", stopwatch.Elapsed));

            var tasks = new List<Task>() { friesTask, drinkTask, burgerTask };
            
            while (tasks.Count > 0)
            {
                var task = await Task.WhenAny(tasks);
                tasks.Remove(task);

                Console.WriteLine($"Yum! {tasks.Count} left!");
            }

            ShowCompletion("Order", stopwatch.Elapsed);

            stopwatch.Stop();
        }

Running this, the burger task will timeout and an exception will be thrown. Since we’re not actually checking for this, all we see in the output is that the burger task finished after 4 seconds instead of 5.

Drink completed after 00:00:01.0819761
Yum! 2 left!
Fries completed after 00:00:03.0493526
Yum! 1 left!
Burger completed after 00:00:04.0952924
Yum! 0 left!
Order completed after 00:00:04.0974441

By putting a breakpoint or turning on first chance exceptions, though, we see that the TimeoutException was indeed thrown:

Summary

  1. awaiting tasks one after another will result in sequential execution.
  2. Use Task.WhenAll() to wait for all tasks to complete before proceeding.
  3. Use Task.WhenAny() to get the first task that finished, and proceed before waiting for the others.
  4. Use Task.WhenAny() in a loop to process all tasks as they arrive, and potentially break out early in case of failure.
  5. Apply a timeout to a task using the TimeoutAfter() extension method from the Parallel Programming blog on MSDN.

Working with Asynchronous Methods in C#

In yesterday’s article, “Motivation for async/await in C#“, we have seen why asynchronous programming is important. We have also seen basic usage of the await keyword, which requires its containing method to be marked as async.

When learning to write asynchronous methods, it is not trivial to get the interactions between various methods (which may or may not be asynchronous) right. In fact, the examples in yesterday’s article which use an async void method should normally only be used in event handlers, and even so, there are caveats to consider.

In this article, we’ll go through various different scenarios in which async/await can be used.

async Task methods

Let’s take another look at the asynchronous (event handler) method from yesterday’s article:

        private async void Button_Click(object sender, RoutedEventArgs e)
        {
            var baseAddress = new Uri("http://mta.com.mt");

            using (var httpClient = new HttpClient() { BaseAddress = baseAddress })
            {
                var response = await httpClient.GetAsync("/");
                var content = await response.Content.ReadAsStringAsync();

                MessageBox.Show("Response arrived!", "Slow website");
            }
        }

Try moving out the code into a separate method, and awaiting it from the event handler. You’ll find that you can’t await an async void method:

In order to be able to await a method, it must return Task (if it doesn’t need to return anything, such as void methods) or Task<T> (if it needs to return a value of type T). We also append an –Async suffix to the method name by convention to make it obvious for people who use such methods that they’re meant to be awaited.

Thus, this example becomes:

        private async void Button_Click(object sender, RoutedEventArgs e)
        {
            await GetHtmlAsync();
        }

        private async Task GetHtmlAsync()
        {
            var baseAddress = new Uri("http://mta.com.mt");

            using (var httpClient = new HttpClient() { BaseAddress = baseAddress })
            {
                var response = await httpClient.GetAsync("/");
                var content = await response.Content.ReadAsStringAsync();

                MessageBox.Show("Response arrived!", "Slow website");
            }
        }

This is an example of an async Task method, which does not return anything. Let’s change it such that it returns the HTML from the response:

        private async void Button_Click(object sender, RoutedEventArgs e)
        {
            string html = await GetHtmlAsync();
        }

        private async Task<string> GetHtmlAsync()
        {
            var baseAddress = new Uri("http://mta.com.mt");

            using (var httpClient = new HttpClient() { BaseAddress = baseAddress })
            {
                var response = await httpClient.GetAsync("/");
                var content = await response.Content.ReadAsStringAsync();

                return content;
            }
        }

We’ve changed the signature of GetHtmlAsync() to return Task<string> intead of just Task. Correspondingly, we are now returning content (a string) from the method. At the event handler, we are now assigning the result of the await into the html variable. Apart from waiting asynchronously until the method completes, await has the additional function of unwrapping the result from the Task that contains it; thus html is of type string.

If you try removing the async keyword from GetHtmlAsync(), you’ll learn a little more about the actual function of the async keyword:

Without async, you are expected to return what the method advertises: a Task<string>. On the other hand, if you mark the method as async, the meaning of the method is changed such that you can return a string directly. The underlying Task-related plumbing is handled by the compiler.

Chaining Asynchronous Methods

In the previous section, we have seen how methods need to return a Task in order to be awaited. Typically, one async Task method will call another and await its result.

The chain of calls ends at a last async Task, typically provided by the .NET Framework or other library, which interfaces directly with I/O (e.g. network or filesystem). It must be an asynchronous method; attempting to disguise a blocking call as async here will lead to deadlocks.

async Task may (and should) be used all the way from an incoming request to the final I/O library method in application types that support top-level asynchronous methods, such as Web API or WCF.

The situation is a little different for other applications (e.g. Windows Forms, WPF) that are event-driven. Asynchronous event handlers are a special case where we need to use async void methods, as we have already seen in the WPF example from yesterday’s article:

async void methods

Event handlers are void methods that are called by the runtime in a dispatcher loop. Thus, async void methods are necessary to allow usage of await within event handlers without requiring them to return a Task

However, as we have seen before, there is no way to await an async void method. This makes async void methods very dangerous to use outside of their intended context, as I have detailed in “The Dangers of async void Event Handlers“. This is one of the more common mistakes when programming with async/await, and it is good to become familiar with the problems in order to avoid repeating the same mistakes in future.

Fake Asynchronous Methods

Sometimes, you’ll have an interface that requires asynchronous methods, yet your implementation does not need anything asynchronous in it. Let’s look at a practical example:

    public interface ISimpleStorage
    {
        Task WriteAsync(string str);
        Task<string> ReadAsync();
    }

You could implement this interface using a simple file as a backing store, in which case your methods will be suitably asynchronous:

    public class FileStorage : ISimpleStorage
    {
        public async Task<string> ReadAsync()
        {
            using (var fs = File.OpenRead("file.txt"))
            using (var sr = new StreamReader(fs))
            {
                var str = await sr.ReadToEndAsync();
                return str;
            }
        }

        public async Task WriteAsync(string str)
        {
            using (var fs = File.OpenWrite("file.txt"))
            using (var sw = new StreamWriter(fs))
            {
                await sw.WriteAsync(str);
                await sw.FlushAsync();
            }
        }
    }

However, you could have another implementation which just uses memory as storage, and in this case there’s nothing asynchronous:

    public class MemoryStorage : ISimpleStorage
    {
        private string str;

        public Task<string> ReadAsync()
        {
            return Task.FromResult(str);
        }

        public Task WriteAsync(string str)
        {
            this.str = str;
            return Task.CompletedTask;
        }
    }

In that case, your methods need not be marked async. However, this means that you will actually need to return Task instances from each method. If you have nothing to return, then just return a Task.CompletedTask (available from .NET Framework 4.6 onwards). You can also use Task.FromResult() to construct a task from a variable that you want to return.

Simplifying Single Line Asynchronous Methods

Consider the following asynchronous method:

        static async Task WaitALittleAsync()
        {
            await Task.Delay(10000);
        }

Here, we are waiting for the delay to finish, and then returning the result.

Instead, we can just return the Task itself, and let the caller do the awaiting:

        static Task WaitALittleAsync()
        {
            return Task.Delay(10000);
        }

Once again, a method does not need to be marked async if (a) it does not await anything, and (b) it can return a Task, rather than some other type that needs to be wrapped in a Task.

Using async/await in Main()

Until recently, you couldn’t use async/await in a console application’s Main() method. You can have an async Task Main() method as from C# 7.1, but you need to make sure you’re using C# 7.1 first from your project properties -> Build -> Advanced…:

You can choose either “C# 7.1”, or “C# latest minor version (latest)”. With that, you can await directly from within Main():

        static async Task Main(string[] args)
        {
            await WaitALittleAsync();
        }

Before C# 7.1, you had to use some other workaround to await from Main(). One option is to use a special AsyncContext such as the one written by Stephen Cleary. Another is to just move asynchrony out of Main() and use a Console.ReadLine() to keep the window open:

        static void Main(string[] args)
        {
            Run();
            Console.ReadLine();
        }

        static async void Run()
        {
            await WaitALittleAsync();
        }

Summary

  1. Use async Task methods wherever you can.
  2. Use async void methods for event handlers, but beware the dangers even there.
  3. Use the –Async suffix in asynchronous method names to make them easily recognisable as awaitable.
  4. Use Task.CompletedTask and Task.FromResult() to satisfy asynchronous contracts with synchronous code.
  5. Asynchronous code in Main() has not been possible until recently. Use C# 7.1+ or a workaround to get this working.

Motivation for async/await in C#

Introduction

In .NET 4.5, the async and await keywords were introduced. They are now a welcome and ubiquitous part of the .NET developer’s toolkit. However, I often run into developers who are not familiar with this concept, and I have had to explain async/await many times. Thus, I felt it would make sense to write up this explanation so that it can be accessible to all.

async/await is really just syntactic sugar for task continuations, but it makes asynchronous, I/O-bound code very elegant to work with. In fact, it is so popular that it has been spreading to other languages such as JavaScript.

As far as I can remember, async/await was introduced mainly to facilitate building Windows Phone applications. Unlike desktop applications, Windows Phone had introduced a hard limit in which no method could block for more than 50ms. Thus it was no longer possible for developers to resort to blocking their UI, and the need arose to use asynchronous paradigms, for which tasks are a very powerful, but sometimes tedious, option. async/await makes asynchronous code look almost identical to synchronous code.

In this article, I will not go into detail about using Tasks in .NET (which deserves a whole series of articles in itself), but I will give a very basic explanation on how to use them for asynchronous processing. More advanced usage is left for future articles.

Sidenote: Rejoice, for this is the 200th article published on Gigi Labs!

Motivation

Although async/await can be used in all sorts of applications, I like to use WPF applications to show why it’s important. You don’t need to know WPF for this; just follow along.

Let’s create a new WPF application, and simply drag a button from the Toolbox onto the WPF window:

Double-clicking that button will cause a click event handler to be generated in the codebehind class (MainWindow.xaml.cs):

        private void Button_Click(object sender, RoutedEventArgs e)
        {

        }

Now, let’s be evil and toss a Thread.Sleep() in there:

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            Thread.Sleep(15000);
        }

Run the application without debugging (Ctrl+F5) and click the button. Try to interact with the window (e.g. drag it around). What happens?

The UI is completely frozen; you can’t click the button again, drag the window, or close it. That’s because we’ve done something very, very stupid. We have blocked the application’s UI thread.

Let us now replace the Thread.Sleep() with this Task.Delay() instead (notice there is also that async in the method signature, and it’s important):

        private async void Button_Click(object sender, RoutedEventArgs e)
        {
            await Task.Delay(15000);
        }

If you run the application now, you’ll find that you can interact with the window after clicking the button, even though the code appears to be doing practically the same thing as before. So what changed?


Image taken from: Asynchronous Programming with Async and Await (C# and Visual Basic)

The way control flow works with async/await is explained in detail on MSDN, but it may feel a little overwhelming if you’re learning this the first time. Essentially, to understand what is happening, we need to break that await Task.Delay(15000) line into the following steps:

  1. Task.Delay(15000) executes, returning a Task representing it. It does not block since it does not necessarily execute on the same thread.
  2. Because of the await, execution of the remainder of the method is temporarily suspended. In terms of method execution, it’s as if we’re blocking.
  3. Eventually, the Task finishes executing. The await part is fulfilled, and the remainder of the method can resume execution.

async/await with HttpClient

Using a simple delay is a nice way to get an initial feel of async/await, but it is also not very realistic. async/await works best when you are dealing with I/O requests such as sockets, databases, NoSQL storage, files, REST, etc. To this effect, let’s adapt our example to use an HttpClient.

First, let’s install the following package via NuGet:

Install-Package Microsoft.Net.Http

We’re going to repeat the same experiment as before: first we’ll do a silly blocking implementation, and then we’ll make it asynchronous.

Let’s work with this code that gets the response from the Google homepage:

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            var baseAddress = new Uri("http://www.google.com");

            using (var httpClient = new HttpClient() { BaseAddress = baseAddress })
            {
                var response = httpClient.GetAsync("/").Result;
                var content = response.Content.ReadAsStringAsync().Result;
            }
        }

If we run this and click the button, the window blocks for a fraction of a second, and we get back the HTML from Google:

Google has a very fast response time, so it is a poor example for visualising the problems of blocking code in a UI. Instead, let’s use a website that takes a very long time to load. One that I’ve written about before is that of the Malta Tourism Authority, which takes over 20 seconds to load. Let’s change our base address in the code:

            var baseAddress = new Uri("http://mta.com.mt");

If you run the application now and click the button, you’ll see that it will be stuck for a fairly long time, just like before. We can sort this out by making the request asynchronous. To do that, we replace each .Result property with an await. In order to use await, we have to mark the method as async. In order to get a notification when the response actually comes back, I’ll also toss in a message box:

        private async void Button_Click(object sender, RoutedEventArgs e)
        {
            var baseAddress = new Uri("http://mta.com.mt");

            using (var httpClient = new HttpClient() { BaseAddress = baseAddress })
            {
                var response = await httpClient.GetAsync("/");
                var content = await response.Content.ReadAsStringAsync();

                MessageBox.Show("Response arrived!", "Slow website");
            }
        }

Run the application and click the button. You can interact with the window while the request is processed, and when the response comes back, you’ll get a notification:

If you put a breakpoint and follow along line by line, you’ll see that everything happens sequentially: the content line will not execute before the response has arrived. So async/await is really just giving us the means to make asynchronous code look very similar to normal sequential execution logic, hiding the underlying complexities. However, as we’ll see in later articles, it is also possible to use this abstraction for more powerful scenarios such as parallel task execution.

The Importance of Asynchronous Code

While I have not really explained how to work with async/await in any reasonable depth yet, the importance should now be evident: making I/O calls asynchronous means that your thread does not need to block, and can be freed to do other work. While this has a great impact on user experience in GUI applications, it is also fundamental in other applications such as APIs. Under high load, it is possible to end up with thread starvation when blocking, because all threads are stuck waiting for I/O, when they could otherwise be processing requests.

For pure asynchronous code, blocking isn’t actually ever necessary. When an I/O request such as HttpClient.GetAsync() is fired, .NET uses something called I/O Completion Ports (IOCP) which can monitor incoming I/O and trigger the caller to resume when ready.

We have merely scratched the surface here. There is a lot to be said about async/await, and likewise there are a lot of pitfalls that one must be made aware of. This article has shown why asynchronous code is important, and future articles may cover different aspects in more detail.

The Adapter Design Pattern for DTOs in C#

In this article, we discuss the Adapter design pattern, which is part of the book “Design Patterns: Elements of Reusable Object-Oriented Software” by Gamma et al. (also known as the Gang of Four).

We will discuss the motivation for this design pattern (including common misconceptions) and see a number of different ways in which this pattern is implemented in C#.

TL;DR Use extension methods for your mapping code.

Defining the Interface of a Class

The above book summaries the Adapter pattern thusly:

“Convert the interface of a class into another interface clients expect. Adapter lets classes work together that couldn’t otherwise because of incompatible interfaces.”

It is fundamental to interpret this description in the context in which it was written. The book was published in 1994, before Java and similar languages even existed (in fact, the examples are in C++). Back then, “the interface of a class” simply meant its public API, to which extent “client code” could use it. C++ has no formal interface construct as in C# and Java, and the degree of encapsulation is dictated as a result of what the class exposes publicly. Note that a class’s interface is not restricted to its public methods alone; C++ also offers other devices external to the class itself, and so does C# (extension methods, for instance).

Given today’s languages where interfaces are formal language constructs, such an interpretation has mostly been forgotten. For instance, the 2013 MSDN Magazine article “The Adapter Pattern in the .NET Framework” illustrates the Adapter design pattern in terms of C# interfaces, but it slightly misses the point. We can discuss the Adapter pattern without referring to C# interfaces at all, and instead focus on Data Transfer Objects (DTOs). DTOs are simply lightweight classes used to carry data, often between remote applications.

An Example Scenario

Let’s say we have this third party class with a single method:

    public class PersonRepository
    {
        public void AddPerson(Person person)
        {
            // implementation goes here
        }
    }

The interface of this class consists of the single AddPerson() method, but the Person class that it expects as a parameter is also part of that interface. There is no way that the third party could give us the PersonRepository (e.g. via a NuGet package) without also including the Person class.

It is often the case that we may have a different Person class of our own (we’ll call it OurPerson), but we can’t pass it to AddPerson(), because it expects its own Person class:

    public class Person // third party class
    {
        public string FullName { get; set; }

        public Person(string fullName)
        {
            this.FullName = fullName;
        }
    }

    public class OurPerson // our class
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }

        public OurPerson(string firstName, string lastName)
        {
            FirstName = firstName;
            LastName = lastName;
        }
    }

Thus, we need a way to transform an OurPerson instance into a Person. For that, we need an Adapter. Next, we’ll go through a few ways in which we can implement this.

Constructor Adapter

One way of creating a Person from an OurPerson is to add a constructor in Person which handles the conversion:

    public class Person // third party class
    {
        public string FullName { get; set; }

        public Person(string fullName)
        {
            this.FullName = fullName;
        }

        public Person(OurPerson ourPerson)
        {
            this.FullName = $"{ourPerson.FirstName} {ourPerson.LastName}";
        }
    }

It is not hard to see why this is a really bad idea. It forces Person to have a direct dependency on OurPerson, so anyone shipping PersonRepository would now need to ship an additional class that may be domain-specific and might not belong in this context. Even worse, this is not possible to achieve if the Person class belongs to a third party and we are not able to modify it.

Wrapper

Another approach (which the aforementioned book describes) is to implement OurPerson in terms of Person. This can be done by subclassing, if the third party class allows it:

    public class OurPerson : Person // our class
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }

        public OurPerson(string firstName, string lastName)
            : base($"{firstName} {lastName}")
        {
            FirstName = firstName;
            LastName = lastName;
        }
    }

Where C# interfaces are involved, an alternative approach to inheritance is composition. OurPerson could contain a Person instance and expose the necessary methods and properties to implement its interface.

The disadvantage of either of these two approaches is that they make OurPerson dependent on Person, which is the opposite of the problem we have seen in the previous approach. This dependency would be carried to wherever OurPerson is used.

Especially when dealing with third party libraries, it is usually best to map their data onto our own objects. Any changes to the third party classes will thus have limited impact in our domain.

AutoMapper

A lot of people love to use AutoMapper for mapping DTOs. It is particularly useful if the source and destination classes are practically identical in terms of properties. If they’re not, you’ll have to do a fair amount of configuration to tell AutoMapper how to construct the destination properties from the data in the source.

Personally, I’m not a fan of AutoMapper, for the following reasons:

  • The mapping occurs dynamically at runtime. Thus, as the DTOs evolve, you will potentially have runtime errors in production. I prefer to catch such issues at compile-time.
  • Writing AutoMapper configuration can get very tedious and unreadable, often more so than it would take to map DTOs’ properties manually.
  • You can’t do anything asynchronous in AutoMapper configuration. While this may sound bizarre, I’ve needed this in the past due to terrible DTOs provided by a third party provider.

Standalone Adapter

The aforementioned MSDN Magazine article simply uses a separate class to convert from source to destination. Applied to our example, this could look like this:

    public class PersonAdapter
    {
        public Person ConvertToPerson(OurPerson person)
        {
            return new Person($"{person.FirstName} {person.LastName}");
        }
    }

We may then imagine its usage as such:

            var ourPerson = new OurPerson("Chuck", "Berry");
            var adapter = new PersonAdapter();
            var person = adapter.ConvertToPerson(ourPerson);

This approach is valid, and does not couple the DTOs together, but it is a little tedious in that you may have to create a lot of adapter classes, and subsequently create instances whenever you want to use them. You can mitigate this a little by making them static.

Extension Methods

A slight but very elegant improvement over the previous approach is to put mapping code into extension methods.

    public static class OurPersonExtensions
    {
        public static Person ToPerson(this OurPerson person)
        {
            return new Person($"{person.FirstName} {person.LastName}");
        }
    }

The usage is very clean, making it look like the conversion operation is part of the interface of the class:

            var ourPerson = new OurPerson("Chuck", "Berry");
            var person = ourPerson.ToPerson();

This works just as well if you’ve converting from a third party object onto your own class, since extension methods can be used to append functionality even to classes over which you have no control.

Summary

There are many ways to apply the Adapter design pattern in mapping DTOs. Extension methods are the best approach I’ve come across for C# because:

  • They don’t couple the source and destination DTOs.
  • The conversion occurs at compile time, so any repercussions of changes to the DTOs will be caught early.
  • They can easily be used to append functionality even to third party classes for which the source code is not available.

The Adapter design pattern has little to do with interfaces as a formal OOP language construct. Instead, it deals with “the interface of a class”, which is embodied by whatever it exposes publicly. The Adapter design pattern provides a means to work with that interface by converting incompatible objects to ones that satisfy its contract.

On Stack Overflow

love Stack Overflow. As a software developer, I think it is one of the most important and useful resources ever made, helping me quickly resolve countless issues in my work and side projects.

I also hate it with a passion, and think it can be a royal pain in the ass. My main reasons for this stem from the community, especially those with moderation powers, being made up of a bunch of kids (not necessarily in the physical sense) who are addicted to the gamification system and will do anything to ramp up their reputation.

Given that I ask about as many questions as I answer, the result was that I have seen many of my legitimate questions closed and/or downvoted for various reasons such as “not constructive” or “duplicate”. Many times, the people casting such judgement would not actually understand the question.

One of my biggest frustrations with the site came when I asked the question “Task.Factory.FromAsync with CancellationTokenSource“. A troll with very high reputation (read: mod_powers++) marked this question as a duplicate of another question which had nothing to do with mine. When I challenged him, he went as far as to edit the unrelated question such that it did answer my question. He actually admitted this in the comments to my question (which have by now been cleaned up by moderators after I reported the matter, but I have conveniently kept screenshots), and even asked me to offer a bounty so that he could get more points:

As a regular user of Stack Overflow, I was highly put off at not being able to ask any reasonable question without it being closed down.

Answering questions is just as frustrating. Typically, when a question is asked, a barrage of short, two-sentence answers will appear. These will be progressively edited into better answers, but as long as they can get something in initially, they will start accumulating points. This is a common tactic and discourages spending the time to write well-thought answers for relatively little reward. Not that I believe that the reward system is more important than the quality of the questions and answers. But alas, many people do, and that is the reason for this sort of phenomenon.

And you can tell that something is really messed up when you get entire courses, such as this 6-hour Pluralsight course, explaining how to use something that is supposed to be a Q&A site.

But in fact, what I am describing is nothing new, and has been going on for many years. In fact, around 2013, Michael Richter wrote a very informative post about the problems plaguing Stack Overflow. It has disappeared from its original location, but can still be read (along with around a couple of weeks’ worth of comments) thanks to the Internet Archive.

I am reproducing Mr. Richter’s article below for ease of future reference. Aside from the issues with Stack Overflow, I would also like to emphasise the story around his “goto” answer, which reverberates a problem I encounter extremely regularly with developers being too religious about what they have been taught, and not using their head to adequately reason about techniques in the particular context they need.

Without further ado…

“Why I no longer contribute to StackOverflow” by Michael Richter

I was active in the StackOverflow (and the broader Stack Exchange) community for a while. I no longer am. Here’s why.

Introduction

I have an account at StackOverflow. Follow the link and check out a few stats:

  • I’ve been a member for almost four years at the time I’m writing this.
  • I’ve scored over 14,000 points in their gaming system.
  • I’m in the top 3% of their contributors overall as of this writing.

I point this out not to brag but to make sure it’s clear that I’m not writing this because of “sour grapes” or because I’m not getting the recognition I think I deserve. Indeed, to be blunt, I’m getting way too much recognition, but more on that below.

Overview

If you’re a software developer of any kind, and if you haven’t been sleeping under a rock, you know of Joel Spolsky and Jeff Atwood’s StackOverflow (and broader StackExchange ecosystem). For the rest of you, allow me to lift up your rock a little and explain what the site is.

In brief, you ask questions related to programming and other people answer them. The site is “gamified” (what an utterly horrendous neologism, that!) so you score points for asking questions that get voted up, answering questions and getting voted up, for doing book-keeping tasks and a variety of other things. You can also earn “badges” (gold, silver and bronze) for accomplishing certain things.

The intent of the system is to provide some form of recognition for people who help others with software development problems. It sounds innocuous, but in the end I find it vaguely distasteful and off-putting.

I’ve been asked more than a few times now why I think this, so today I will commit my explanations in writing once so I can just point to this page instead of repeatedly saying the same thing.

The problems

The problems I see with StackOverflow are summarized in this list:

  1. Poor pedagogy
  2. Poor reward system
  3. Poor community

I’m willing to engage in discussion of any of these flaws. Comments are turned on for this post. They are, however, moderated so if you plan to simply spew bile at someone who dares say bad things about a site you like you:

  • won’t get your 15 seconds of Innarwebs Fame™®;
  • will add to this counter of people who contribute to point #3 above: count so far: 6

Poor pedagogy

As an educator, I find the StackOverflow approach to “helping” people unproductive and contrary to any kind of real learning. For illustration, go back and take a look at my profile. Specifically take a look at the tags tab. See the #1 tag there? Java. Most of my answers (and most of my points) come from Java-related questions.

Now comes a confession.

I’m not a Java programmer. I’ve only ever briefly programmed in Java professionally. I hated the experience and I hate the language. I certainly don’t consider myself a Java expert. Yet I managed to get the bulk of my points from Java. How is this possible?

It’s possible because I did what many of the people whose questions I answered (and got points for) should have done for themselves: I saw a simple Java question, hit Google, read briefly, then synthesized an original answer.

There’s an old cliché in English: give a man a fish, he eats for a day; teach a man to fish, he eats for a lifetime. StackOverflow is filled to the brim with people giving fishes. The people asking are learning nothing useful beyond the shortest of the short terms and the people teaching are not helping in any but the most trivial of ways. In the long term, I submit, StackOverflow is probably holding back the development of programmers (and thus the entire field of programming).

Poor reward system

Incidentally, my #2 tag is C++. There was a time I would cheerfully have called myself a C++ expert. These days I still likely know more about the language than most people working in it, but I have, if it’s at all possible, an even deeper abiding hatred of the language than I do for Java.

So why, if I hate Java and C++ (and several other languages that score well on my tags list), do I bother answering questions on those topics? This is because of the second problem I have with StackOverflow: the reward system is ludicrously designed.

The high school “cool kids table”

The very nature of StackOverflow’s structure has it such that only those who answer simple questions of the most popular programming languages will get a reward. To illustrate this, look at the difference between this Java-related answer and this non-Java one.

The Java answer scored me 460 and took me probably under a minute to write. The one about operating systems scored me 60 points and likely took about fifteen minutes to write.

If you’re going for points (and that’s the entire raison d’être for gamification!), are you going to waste time like that for 60 points when you could fit in a dozen 460-point answers? Of course not! You’re going to go wherever the points are, And the points are the low-hanging fruit of trivial questions from popular languages. The way StackOverflow is structured rewards people who put as little work as possible across as many simple questions as possible within only the most popular segments. Spending thought (and thus time) on answers interferes with points- and badge-mongering. Answering questions outside of the top ten languages similarly interferes.

This “cool kids table” problem has a very real effect. Look again at my profile. 218 answers. 10 questions. Why is this? I could arrogantly claim that this is because I know more than everybody else, but the real reason is that getting answers on any question that requires thought is a non-starter. As my approach to scoring points (Google + hasty rewrite) shows, I’m quite adept at answering trivial questions myself. For a prime example of the problem, consider this question. It got five answers (one of which you probably can’t see), only one of which even really answered part of the question. Why? Because answering the whole question would have taken a lot more work than most people in StackOverflow would be willing to put in. There’s just no percentage in spending time on difficult questions when you can hoover up a cool thousand points in a fraction of the time.

Broken scoring

Even if the “cool kids table” wasn’t an issue at StackOverflow, the system is still largely broken. Remember how I have over 14,000 points as of this writing? Two years and a bit ago, when I decided to stop participating in StackOverflow, this was not the case. I was “only” at OVER NINE THOUSAND! and several hundred points shy of getting moderator status. In well over two years I have contributed nothing to StackOverflow: no questions, no answers, nothing. (Well, that’s not true. When my score went over 10,000 I tried out the moderator powers for a couple of edits, just to test them out.) Over one third of my reputation was “earned” from me doing absolutely nothing for over two years. Indeed I went from the top 4% of contributors at my time of departure to the top 3%, despite, you know, me not doing anything.

Any scoring system that allows this to happen is simply broken in my opinion.

Poor community

And now my reputation score will go down!

Petty children

As of this writing my score was, as mentioned above, over 14,000. (14,076 to be precise.) I predict that this is going to go down as more people find out about this blog entry and start voting down my questions and answers in petty revenge. How do I know? I’ve been on the receiving end of sudden bouts of negative votes before. Consider this question about ‘goto’ constructs, for example. As of this writing it has 72 up votes and 13 down votes. It is simultaneously one of my most popular answers as well as one of my most hated ones.

The people who hated it weren’t content, however, with merely voting it down. No, after I posted that answer I had a mysterious downward turn in my reputation as downvotes appeared all over my answers. People got so upset at my mocking one of the Holy of Holies of computing that it wasn’t enough to just downvote the answer, they had to punish me. (Their selected means of punishment was as highly amusing as it was highly ineffective.) This is not the way a community of mature users acts.

Creeping authoritarianism

That kind of behaviour is, of course, inevitable in any kind of Innarwebs™® interaction. Pseudo-anonymity makes doorknobs of otherwise-normal people. There is something else, however, in the whole Stack Exchange hierarchy that bugs me: the creeping authoritarianism.

The “flavour” of StackOverflow today is entirely different than the flavour it had when I started. When I started the community as a whole still had a bit of a sense of humour. Sure sometimes questions and/or answers would be a bit off-topic or a bit irreverent, but it gave more of a community feel that way, even if it was on occasion less-than-“professional”.

This changed slowly but surely in the way that all “community moderated” things change. Here is the recipe that all such “community-driven” approaches almost, but not quite, invariably follow:

  1. A wide-open community based on “merit” is built.
  2. The community gets a kernel of users who build up “merit” by virtue of, basically, being obsessive twerps.
  3. As this kernel of “serious” users builds up its influence, they start to modify what the standards of the community are to match their own desires.
  4. These standards get enforced on other members of the community who lack sufficient “merit” (read: who have a life outside the site) to fight back.
  5. The tenor of the community changes to match the notions of the obsessive, but “meritous” minority.
  6. Lather. Rinse. Repeat.

This happened at Wikipedia and it’s happened at StackOverflow. StackOverflow was once fun. It is no longer. StackOverflow once had a tolerance for things a little outside of the norm. It does no longer.

Take a look at the site now. Some of the most popular questions and/or answers are now locked down and only kept for “historical reasons”. Consider this answer. It’s likely the best-known and most-loved answer on the entire damned site! It’s funny and it’s informative. But it’s something that makes the current powers-that-be at the site crazy and thus it is locked and we have this ominous note appended: “This post has been locked while disputes about its content are being resolved.”

What. The. Fuck!?

TL;DR

There are a number of reasons why I stopped contributing to StackOverflow. I am disquieted by its poor pedagogical value, I think its scoring system is fundamentally broken and rewards the wrong things, and I think its community lacks maturity even while it becomes more and more pointlessly authoritarian. So what would I recommend as an alternative?

How about learning? You know, that thing that puts information in your head that you can apply later at need. Use Google. Use Wikipedia (if you must). Use RosettaCode for code examples. (Contribute there too!) Engage with other users of the tools you use in the form of user groups, mailing lists, web forums, etc. Learn foundational principles instead of answers to immediate questions.