Archive

Last week, we announced the pre-release of PostSharp Threading Toolkit, a library of aspects implementing best-practice patterns of multithreaded applications. The toolkit is available on NuGet and its source code is hosted on GitHub.

Note: the source code of the ping-pong example is available on GitHub too.

The Right Level of Abstraction

The motto of this toolkit is that direct use of the System.Threading namespace brings so much complexity that it cannot scale to large object models. In other words, if you’re using System.Threading or just locks in your business or UI layer (except in a few very specific classes), you are probably addressing the threading concern at the wrong level of abstraction, and you and your co-workers will perhaps have difficulties to handle that complexity in large applications.

A far better approach to multithreading is to grab a few threading models and to make sure everyone understands them. Then, select the proper threading model for every part of your application (UI and domain will probably require a different threading model). Finally, implement the threading model in all your classes. That final step is obviously the most complex and time-consuming (there can be thousands of classes) and cancels the benefits of abstraction – unless you are getting the tools for the job: Erlang, F#, or… PostSharp Threading Toolkit.

The Bad: Mutable Shared State

Imagine you have a room full of accounting assistants all working on the yearly balance of the same company. To make it easier to share information among workers, the manager thought it was smart to decide that all accounts will be maintained on a blackboard, so that many workers can update it simultaneously. (I chose a blackboard on purpose, because if whiteboards existed, they would probably have chosen a computer.)

It’s clear that workers of this team need to cooperate (i.e., communicate) in order to get their jobs done, otherwise they are going to overwrite each other’s accounting lines and mess with the balance.

The moral in the fable: concurrent access by several workers to shared mutable state causes mess.

A state (typically: a field or an element array) is mutable if it can be modified. It is shared if it can be read or updated by several workers concurrently. Immutable shared state does not cause conflict (all workers can concurrently look at the President’s picture on the wall). Private mutable state is safe too (there would be no issue if every worker was assigned a single account).

Actors Against Mutable Shared State

Actor-Based Programming (or simply actors) address the problem of multithreaded software by eradicating mutable shared state. Formally, the Actor model wants to ensure that, for any state:

     NOT (state is mutable AND state is shared).

In other words, the Actor model ensures that:

     state is mutable XOR state is shared.

The Actor model implements these restrictions using – guess what: actors! Think of as Actor as an object-oriented class (with some children objects such as collections, perhaps).

The Actor model is based on the following principles:

  • Actors communicate between each other and with the rest of the world using messages.
  • Messages are immutable.
  • An actor process only one message at a time.
  • Processing messages may cause a change of the state of the actor that processes it. Other state changes must be ordered through message passing.

The principles ensure that the only mutable state is private to an actor, and since the message-passing mechanism guarantees actors are single-threaded, the mutable state is not shared among different processors.

These simple principles are at the origin of the success of Erlang and F#, but have traditionally been difficult to implement in C#. With the new C# 5.0 and PostSharp Threading Toolkit, this is now much easier!

A Simple Ping-Pong Game

Let’s see these principles in action on the simplest multi-actor game invented: ping-pong. To make the game a little more interesting (and show that execution is actually asynchronous), I’m throwing two balls in the game.

class Player : Actor
{
    string name;
    int counter;

    public Player(string name)
    {
        this.name = name;
    }

    public void Ping(Player peer,  int countdown)
    {
        Console.WriteLine("{0}.Ping from thread {1}", this.name, 
Thread.CurrentThread.ManagedThreadId); if (countdown >= 1) { peer.Ping(this, countdown - 1); } this.counter++; } } class Program { static void Main(string[] args) { Player ping = new Player("Sarkozy"); Player pong = new Player("Hollande"); ping.Ping(pong, 4); ping.Ping(pong, 4); Console.ReadLine(); } }

This program gives the following output:

Sarkozy.Ping from thread 3
Sarkozy.Ping from thread 3
Hollande.Ping from thread 4
Hollande.Ping from thread 4
Sarkozy.Ping from thread 3
Sarkozy.Ping from thread 3
Hollande.Ping from thread 4
Hollande.Ping from thread 4
Sarkozy.Ping from thread 6
Sarkozy.Ping from thread 6

As you can see, actors run on a different thread than the Main method. Calling the Ping method results in a message to be appended to the actor’s message queue. When a message queue was empty and got its first message, the dispatcher creates a Task to process the message queue. Therefore, actors run on the thread pool and there’s no need to have one thread per actor.

Note that the field Player.counter is incremented by the Ping method. Incrementing consists in reading and writing a field atomically. In a concurrent environment, we should have used Interlocked.Increment. But since the field is private to the actor, we don’t have to think about data races.

Build-Time Validation

I’ve said that the Player.counter field is safe because it’s private. I meant that logically it belongs to the private state of the actor, as opposed to the state that is shared among actors and threads. That said, private is also a C# concept, so what if the field was public?

We thought about this issue, and we designed the toolkit to minimize the level of thinking necessary to apply a threading model, so the toolkit will warn you of any potential error with the following build-time error message:

1>------ Build started: Project: TestAsync, Configuration: Debug Any CPU ------
1>POSTSHARP : postsharp error THR005: Field Player.counter must be private or 
protected because the Player class is an Actor. 1>POSTSHARP : postsharp error PS0060: The processing of module "TestAsync.exe" was
not successful. ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

The toolkit does not claim it’s smarter than you, but it prevents you (and more likely your co-workers) from obvious mistakes. If you decide that a public field is really what you want, you have to annotate the field with the [ThreadUnsafe] custom attribute, which opts out from the safety net enforced by the toolkit.

In a similar spirit, the toolkit will prevent an actor to expose public method that return a value or have ref or out parameters. Why? Because these methods are modified to run asynchronously, so output values could not be known at the time the asynchronous call completes (asynchronous means that the execution continues after the call completes).

If you think this is an awful limitation, you’re right. But we have some good news for you.

Where C# 5.0 Saves the Day

The C# feature of the year is the ability to work with asynchronous methods thanks to two new keywords: async and await. The async keyword basically allows the use of the await keyword, which suspends the execution of the method until some task (or anything “awaitable”) completes. This is exactly what we need to get actor methods return some output to the caller.

Suppose we want to add a GetCounter method to the Player class. We could simply do that:

public async Task<int> GetCounter()
{
    return this.counter;
}

Intellisense gives some warning that there is no async keyword and the method will therefore run synchronously, but PostSharp adds some magic to make the method run asynchronously from the message queue of the Actor. You don’t have to take care of that and can safely ignore the compiler warning.

Now, suppose we call GetCounter just after we call Ping. The message is going to be queued just after the first Ping messages, we we’re probably going to get a counter value of 1. This is not what we want: we want to get the counter after the ping-pong game is finished. To achieve that, we need to make the Ping method awaitable by using the async and await keywords.

Here is the updated source code of our new ‘awaitable’ actor game:

class Player : Actor
{
    string name;
    private int counter;

    public Player(string name)
    {
        this.name = name;
    }

    public async Task<int> GetCounter()
    {
        return this.counter;
    }

    public async Task Ping(Player peer, int countdown)
    {
        Console.WriteLine("{0}.Ping({1}) from thread {2}", this.name, countdown, 
Thread.CurrentThread.ManagedThreadId); if (countdown > 1) { await peer.Ping(this, countdown - 1); } this.counter++; } [ThreadSafe] public override string ToString() { return this.name; } } class Program { static void Main(string[] args) { AsyncMain().Wait(); } private static async Task AsyncMain() { Player ping = new Player("Sarkozy"); Player pong = new Player("Hollande"); Task pingTask = ping.Ping(pong, 4); Task pongTask = pong.Ping(ping, 4); await pingTask; await pongTask; Console.WriteLine("{0} Counter={1}", ping, await ping.GetCounter()); Console.WriteLine("{0} Counter={1}", pong, await pong.GetCounter()); } }

 

Is PostSharp Necessary Anyway?

You could wonder where is PostSharp in this code. After all, isn’t C# 5.0 all you need? Actually, PostSharp is hidden behind the Actor class. It will modify the code of all public instance methods of actors to make them compatible with the Actor model. If you remove PostSharp, you will perhaps still have asynchronous methods, but they will not respect the Actor model and C# 5.0 alone isn’t going to clean up the multithreaded mess.

Actually, PostSharp adds the following code on the top of the main method of the asynchronous state machine. That seems complex, but it’s actually approximately equivalent to doing an “await Task.Yield()” if the code executes from the wrong context, to force it to be rescheduled in the right context.

if (!this.<>4__this.Dispatcher.CheckAccess())
{
  this.<>t__dispatchAwaiter = Task.Yield().GetAwaiter();
  SynchronizationContext oldContext = SynchronizationContext.Current;
  SynchronizationContext.SetSynchronizationContext
(this.<>4__this.Dispatcher.SynchronizationContext); this.<>t__builder.AwaitUnsafeOnCompleted<YieldAwaitable.YieldAwaiter,
Player.<GetCounter>d__0>(ref this.<>t__dispatchAwaiter, ref this); } else {
// Your original code.
}

Additionally to adding behavior to public methods, PostSharp (the Threading Toolkit, more specifically) ensures that your source code respects some safety rules for the Actor model, and emits build-time errors or run-time exceptions if necessary.

To-Do List

Although the main functionalities are implemented and work fine, there is still a lot of work on the to-do list. For instance, the toolkit does not enforce dispatching of private interface implementation yet, neither callback methods (delegate). Not all build-time and run-time checking are already implemented. Specifically, we don’t check that all messages (method parameters and return values) are immutable or otherwise thread-safe.

Summary

I’ve shown how PostSharp Threading Toolkit, together with C# 5.0, offer a compelling implementation of the Actor threading model. As you can see, proper compiler support (PostSharp is a compiler extension) makes programming much easier because it allows to address a problem at the proper level of abstraction.

In later posts, we’ll talk about other threading models supported by PostSharp Threading Toolkit: reader-writer synchronized, and thread unsafe (or singlethreaded).

Happy PostSharping!


-gael

Were excited to announce the latest addition to our product family: the PostSharp Threading Toolkit. It will help your team 'to build multithreaded applications not only with less code, but with higher reliability as well.

The toolkit is available on NuGet: look for the package PostSharp-Threading-Toolkit. Like its younger brother, the PostSharp Diagnostics Toolkit, it’s source code is available on GitHub. The toolkit is free and open source. Note that you will need a Pro Edition of PostSharp (and Windows and Visual Studio, optionally) to use it, since selling PostSharp is how we make a living.

Feature Quick List

The current version of the toolkit provides the following features:

  • Deadlock detection
  • Actor threading model
  • Reader-Writer Synchronized threading model (with dynamic verification)
  • Thread Unsafe threading model (with dynamic verification)
  • Dispatching of methods to GUI thread
  • Dispatching of methods to background thread

But the toolkit does not just provide features. It implements a consistent and disciplined approach to multi-threading – solutions that scale with large object models. Read on.

How NOT to implement multithreading

We’ve gone through several stages of design. First, we wanted to blow users away with features, and provide an aspect for every kind of lock you could imagine.

Then, we realized there was some truth in that quote from A. Einstein: “No problem can be solved from the same level of consciousness that created it”.

So, if problems with multithreading are created by the need to add code (acquiring a lock, for instance) at method-level, we realized that just generating that code automatically would not solve the problem, because you would still need to think about multithreading at a low level and, worse, every single member of your team would need to understand its details. So we needed to solve the issue at a higher level of abstraction.

Three rules for large-scale multithreading

We designed PostSharp Threading Toolkit for teams who need to make large object models thread-safe and still want to sleep at night. Since multithreading is a recurring problem, we chose to approach it as any recurring problem: with design patterns, “repeatable solutions to recurring problems”. You could implement the design pattern totally by yourself, but the Threading Toolkit makes it much easier.

Rule 1. Assign a threading model to each part of your object model

Different layers of an application architecture typically have different threading requirements. For instance, the View is always single-threaded, whereas the Model is multi-threaded. The first rule is to assign a threading model to each part of your object model.

The Threading Toolkit provides the following threading models:

  • Thread Unsafe Objects (use the ThreadUnsafeObjectAttribute aspect on a class):  Such objects are not designed to be accessed concurrently by several threads.
  • Reader-Writer Synchronized Objects (use the ReaderWriterSynchronizedAttribute aspect on a class): Several threads can access the object in reading concurrently, but only a single thread can access the object in writing.
  • Actors (derive your class from the Actor class): Actors communicate with the external world using asynchronous method calls (or messages). Every actor has a message queue, and only a single message is processed at a time, so actors do not need to take care of concurrency issues. Messages are immutable. Since the only shared state is private to each actor, there is no shared mutable state, so no issue.

Other threading models and design patterns exist, but they are not implemented by the toolkit yet:

  • Transactions: The shared state is managed by a transactional engine, which isolates threads from each other and prevents or handles conflicts for you (using locks, typically).

Rule 2. Document the threading model

Whatever threading model you choose, you need to make sure that everyone in the team understands it from a logical point of view. Then, you need to make very clear which threading model each class is implementing. By doing that, you’re putting the stress on the design intent rather than on its implementation.

If you’ve used an aspect to implement the threading model, the documentation is the presence of the aspect itself, which is signaled in Visual Studio by a PostSharp extension to Intellisense.

Rule 3. Verify all assumptions

If you’re writing a thread-unsafe object, but feel there’s a risk it could be used concurrently by several threads because of bugs and misunderstandings, include assertions in your code and throw an exception if the object is being accessed concurrently by several threads.

If you’re writing a reader-writer synchronized object, you should check that no thread modifies a field if it does not hold a writer lock on its parent. Otherwise, the object state could be corrupted. You should also check that no methods read more than 2 fields (or any field larger than a machine work) without holding a read lock. Otherwise, the method could get inconsistent values.

By adding these assertions, you will be more likely to discover errors during testing. Without assertions, object invariants will break without exception, and errors will appear some time later, and will be much more complex to debug.

Ideally, you should only test assumptions in debug builds, and remove them from release builds. It may be useful to perform load testing in debug mode to find as many threading issues as possible.

If you think that the cost of testing threading assumptions manually is enormous, you’re probably right. This is why the threading aspects add them for you.

PostSharp Threading Toolkit uses both static and dynamic analysis to prevent you from writing dangerous code (when possible), and detect dangerous operations.

Deadlock Detection

Whenever you’re using locks, you’re getting into the risk of deadlocks.

Deadlocks are probably the worse thing that can happen to your application. It becomes unresponsive (it “hangs”) and no error report is produced.

The deadlock detection policy is able to detect some categories of deadlocks and throw an exception when it happens. The exception gives a detailed report of all threads and all locks involved in the deadlock, so you can analyze the issue and fix it.

To add deadlock detection to your project, add the following line:

[assembly: DeadlockDetectionPolicy]

In order to be effective, deadlock detection should be enabled in all projects of your application.

Other features

Besides neat design patterns and deadlock detection, the toolkit offers some method- and field-level aspects.

ThreadSafeAttribute

This custom attribute (which is not an aspect) tells the toolkit that you know what you’re doing, and that it should not generate code to make the method well-threaded, or should not emit warnings and errors when this field is accessed without a lock. This is an opt-out mechanism.

BackgroundMethodAttribute

Use this method to make a method execute in the background. This, practically, makes the method asynchronous.

DispatchedMethodAttribute

Use this aspect on an instance method of a view object (WPF or WinForms) to force it to run on the GUI thread. Works with non-view objects also if they maintain the SynchronizationContext or implement IDispatcherObject.

Today and Tomorrow

That was enough of conceptual writing. I’m going to continue to blog about these features one-by-one and include more code.

Although the main features introduced here are already implemented, PostSharp Threading Toolkit is still under development. Singularly, there is still documentation, and not all static and dynamic verifications have been implemented.

The idea behind the release process of the toolkits is to give early access to deliberately half-baked products, so we can get feedback in time and take it into account into next releases.

So the ball is in your court. What do you think about this approach to multithreading? Are you satisfied of the aspects provided by this toolkit? Any WTF, or any special feature request? We’re here to serve.

Happy PostSharping!

Just a quick note to say we’ve fixed the PostSharp Toolkits so that you can build them from source code. Previously, some artifacts were hardcoded to our development environment.

Note that the objective of the toolkits is to provide you with ready-made implementations, so we encourage you downloading the NuGet packages instead of building from source code.

In order to build the toolkits, follow these steps:

1. Download the source code from GitHub

Clone the repository git://github.com/sharpcrafters/PostSharp-Toolkits.git or download the source code from https://github.com/sharpcrafters/PostSharp-Toolkits.

2. Install PostSharp

You need PostSharp to build the toolkits, but we don’t use NuGet to retrieve it from the network. This is because the build script needs to be compatible with our development environment. The minimal version number of PostSharp you need is specified in the dependencies section of the file $\Build\NuGet\Logging\PostSharpDiagnosticsToolkit.nuspec.

If you’ve installed PostSharp with the setup program, you can go to the next step. Otherwise, you need to create a file named $\Dependencies\PostSharp\PostSharpDir.Custom.targets, which specifies where PostSharp is installed. Note that this file should not be checked into the source control.

Here is the content of this file for our development environment:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <PostSharpDir>c:\src\PostSharp-2.1\Build\bin</PostSharpDir>
  </PropertyGroup>
</Project>

3. Build from Visual Studio or MSBuild

At this point, you will probably want to open the solution PostSharp.Toolkits.sln and build it.

4. Build the NuGet packages

When all binaries are built, you can create the NuGet packages by calling

msbuild Build\NuGet\NuGet.proj

The usual disclaimer

Of course, this blog post has to come with the usual disclaimer that PostSharp Diagnostic Toolkit uses PostSharp SDK, which is officially undocumented and unsupported. That is, we are happy to show you how things work, but we won’t answer questions related to its implementation. The source code of the toolkits itself is largely undocumented and is provided AS IS, and we won’t accept this kind of criticisms.

Happy PostSharping!

-gael