This is the second of two parts. The first one is here: TaskCompletionSource in real life (part 1 of 2)

Yesterday I showed an example of how you can use TaskCompletionSource to mock calls that returns a Task for testing purposes. In the code samples I used an interface called IAsyncWebClient. This was of course no coincidence. WebClient happens to be a good candidate for showing the other major case where I use TaskCompletionSource.

Wrapping async operations that do not follow TPL-supported patterns

It should be no news that asynchronous programming in C# these days revolve around Task objects. Also, it should be no news that asynchronicity is not necessarily the same as starting a new thread for the work. Right from the beginning of .NET you had access to reading and writing streams asynchronously using the BeginRead/EndRead method pairs, along with an IAsyncResult. This would use a mechanism known as I/O completion ports which uses a pool of pre-allocated threads, making it way more efficient than creating new threads for such requests.

The Task Parallel Library supports this pattern through the TaskFactory.FromAsync method, which essentially lets you convert this asynchronous pattern into a Task. Unfortunately there are types in the Base Class Library that has asynchronous functionality but that do not follow this pattern and one of them is the WebClient class.

The pattern used in the WebClient class is that you subscribe to a Completed-event, then you invoke the method that will start the download, and finally the event will be raised when the operation completes (either because it was successful, cancelled or failed).

In yesterday's blog post I used the following interface, invented for the demo code in the article:

public interface IAsyncWebClient
{
    Task<string> GetStringAsync(Uri uri);
}

I want to use this interface to create a type that wraps a WebClient. For natural reasons, this is a tough one to make TDD style, simply because we have external dependencies that are not (easily) mocked (such as a server from which the test can download a document) so this time I will break my habit of presenting a test followed by the implementation. I will simply skip the test part and present the code, with lots of comments in it:

public class AsyncWebClient : IAsyncWebClient
{
    public Task<string> GetStringAsync(Uri uri)
    {
        // create completion source
        var tcs = new TaskCompletionSource<string>();

        // create a web client for downloading the string
        var wc = new WebClient();

        // Set up variable for referencing anonymous event handler method. We
        // need to first assign null, and then create the method so that we
        // can reference the variable within the method itself.
        DownloadStringCompletedEventHandler downloadCompletedHandler = null;

        // Set up an anonymous method that will handle the DownloadStringCompleted
        // event.
        downloadCompletedHandler = (s, e) =>
        {
            // Unsubscribe the event listener (to allow the WebClient to
            // be garbage collected).
            wc.DownloadStringCompleted -= downloadCompletedHandler;
            if (e.Error != null)
            {
                // If the download failed, set the error on the task completion source
                tcs.TrySetException(e.Error);
            }
            else if (e.Cancelled)
            {
                // If the download was cancelled, signal cancellation to the
                // task completion source.
                tcs.TrySetCanceled();
            }
            else
            {
                // If the download was successful, set the result on the task completion
                // source
                tcs.TrySetResult(e.Result);
            }

            wc.Dispose();
        };

        // Subscribe to the completed event
        wc.DownloadStringCompleted += downloadCompletedHandler;

        // Start the asynchronous download
        wc.DownloadStringAsync(uri);

        // Return the Task object from the TaskCompletionSource. This object will be monitored
        // by the calling code for the result, that is provided by the TrySetXxxx calls above.
        return tcs.Task;
    }
}

This way we can use the TaskCompletionSource to provide a Task-based wrapper around a type that provide asynchronous methods, but that deviate from the patterns that are directly supported by the Task Parallel Library.

I have posted this code at my BitBucket repository, slightly extended to also contain cancellation support and a simple winforms client (yes, winforms, I felt a bit retro and lazy).

kick it on DotNetKicks.com


I am working for a great consultancy company called Diversify, located in Sweden. We are hiring skilled .NET developers. If you are interested, don't hesitate to get in touch with me.

This is the first of two parts. The second one is here: TaskCompletionSource in real life (part 2 of 2)

The first time I came in contact with the TaskCompletionSource, it took me a little while to realize its use. I see the same thing happening when I happen to introduce it to someone else as well. It's a bit like when your younger kids come home from nursery school, proudly showing to a drawing they made: "Wow! Pretty! ... Um, what is it?"

So I thought I'd share a couple of real-world examples of when I find the TaskCompletionSource to be very useful.

Faking tasks for testing purposes

Well-designed unit tests communicate a lot of information. If they pass, they inform you that a certain behavior works as expected in your software. If it fails, a well-designed test will give you a rather detailed idea about what it is that is not working. For this reason it's important to be quite aware of what you are actually testing.

Let's say that we have some piece of code that needs to download some document from the internet, and do something with that information. Now we want to write some tests for that functionality. What we want to test is:

  1. What happens when the document is successfully downloaded?
  2. What happens if the download fails?

This is what we want to test. What we do not want to test is the download mechanism itself. We don't want our test to fail because the build server doesn't have an Internet connection, or because the URL that you chose for testing happens to be unreachable. Obviously, we want to mock that part of the code. In this example, the object under test will require the calling code to inject an object that is used for downloading the content. For that purpose I made the following interface:

public interface IAsyncWebClient
{
    Task<string> GetStringAsync(Uri uri);
}

As you can see, it represents functionality that can start an asynchronous download, returning a Task<string> for handling the result.

Here is a simple example of that (using Moq). The Worker class has a method called ProcessUri, that will return true or false indicating whether it was successful or not:

[Test]
public void ProcessUri_DownloadSucceeds_True()
{
    // Create a TaskCompletionSource for the test
    var tcs = new TaskCompletionSource<string>();
    // Create a mock for the IAsyncWebClient interface
    var asyncWebClientMock = new Mock<IAsyncWebClient>();
    var uri = new Uri("file://fake");

    // Configure the web client mock for calls to the GetStringAsync method
    // with the given uri. When invoked, it will assign the string "content"
    // as the result of the task from the TaskCompletionSource. We also configure
    // the mock to return the Task object from the TaskCompletionSource.
    asyncWebClientMock
        .Setup(mock => mock.GetStringAsync(uri))
        .Callback(() => tcs.TrySetResult("content"))
        .Returns(tcs.Task);

    // Create the Worker to test, passing in the mocked web client
    var worker = new Worker(asyncWebClientMock.Object);
    // Call the ProcessUri method and wait for the result.
    var result = worker.ProcessUri(uri).Result;

    // Verify that the result is true
    Assert.IsTrue(result);
}

That is a simple test for a happy-flow scenario. And here is a very simple (and naïve) implementation that makes the test pass:

public class Worker
{
    private readonly IAsyncWebClient asyncWebClient;
    public Worker(IAsyncWebClient asyncWebClient)
    {
        this.asyncWebClient = asyncWebClient;
    }

    public Task<bool> ProcessUri(Uri uri)
    {
        return asyncWebClient
            .GetStringAsync(uri)
            .ContinueWith(task => task.Result.Length > 0);
    }
}

As you can see, ProcessUri will blindly assume that the GetStringAsync task will succeed. Let’s add another test for the fail scenario; if the download throws a WebException:

[Test]
public void ProcessUri_DownloadFails_False()
{
    // Arrange
    var tcs = new TaskCompletionSource<string>();
    var asyncWebClientMock = new Mock<IAsyncWebClient>();
    var uri = new Uri("file://fake");

    asyncWebClientMock
        .Setup(mock => mock.GetStringAsync(uri))
        .Callback(() => tcs.TrySetException(new WebException()))
        .Returns(tcs.Task);

    // Act
    var worker = new Worker(asyncWebClientMock.Object);
    var result = worker.ProcessUri(uri).Result;

    // Assert
    Assert.IsFalse(result);
}

As you can see, this time we use the Callback method of the mock to assign a WebException as the result of the task from the TaskCompletionSource. The ProcessUri method is updated to make that (and the previous) test pass:

public Task<bool> ProcessUri(Uri uri)
{
    return asyncWebClient
        .GetStringAsync(uri)
        .ContinueWith(task =>
        {
            if (task.IsFaulted)
            {
                return false;
            }
            return task.Result.Length > 0;
        });
}

Now you have seen an example of how to use TaskCompletionSource to simulate asynchronous tasks for testing purposes, giving you the ability to mock Task objects and their result. This is one of the two main cases where I use it in my daily work. Tomorrow I will present the other case. Oh the suspense.

kick it on DotNetKicks.com


I am working for a great consultancy company called Diversify, located in Sweden. We are hiring skilled .NET developers. If you are interested, don't hesitate to get in touch with me.

...or "making ConcurrentDictionary.GetOrAdd a bit safer".

How many times have you written the "double-check locking" code when adding stuff to a dictionary? You know, the "does the dictionary contain this key? No, ok, so we take a lock. How about now, the key is still not present? No? OK, good, then let’s add it." drill. Code-wise, it would typically look something like this:

if (!dictionary.ContainsKey(key))
{
    lock (dictionaryLock)
    {
        if (!dictionary.ContainsKey(key))
        {
            dictionary.Add(key, value);
        }
    }
}

It’s not particularly pretty, is it? The signal-to-noise ratio of that code is pretty low, so it’s nice to see that something was done in the base class library to address this not uncommon scenario: the ConcurrentDictionary. Using one of those instead, the above code could be distilled down to this:

dictionary.TryAdd(key, value);

Yes, that’s it. This will check if the key exists in the dictionary and if it doesn’t the value will be inserted and associated with that key. All done in a manner that will guarantee that the value will be inserted only once.

In many cases, you will also want to use the value that is either already present in the dictionary, or the one that you just inserted. What I used to do with the old Dictionary was to simply add a line after all the double-check locking code that would pull out he value from the dictionary:

if (!dictionary.ContainsKey(key))
{
    lock (dictionaryLock)
    {
        if (!dictionary.ContainsKey(key))
        {
            dictionary.Add(key, value);
        }
    }
}

var valueToUse = dictionary[key];

While you can still do that with the ConcurrentDictionary (first add, then fetch the value), there is a more convenient way:

var valueToUse = dictionary.GetOrAdd(key, value);

This will check in the dictionary if the key is present. If the key was not present, the value that was provided in the second argument will be inserted. Finally the value associated with the key is returned. Again, this is done in a way that ensures that only one attempt to insert he key into the dictionary is done.

So, what’s the problem?

Now, let’s say that the second argument, the default value, is in fact a method call that will spawn some process of some kind, and that we would not want to start that task unless the key does not already exist. Well, luckily the designers of the ConcurrentDictionary thought about this, so they added an overload taking a Func that can provide the default value:

Task task = dictionary.GetOrAdd(key, k => CreateTaskForKey(k));

This means that the method CreateTaskForKey will not be executed unless the Func is called. That should work, right? Well, it might. And it might not. It is certainly not safe. You see, there is no guarantee that the Func will be executed only once for each key. The only guarantee is that each key (with an associated value) will be inserted into the dictionary only once.

It turns out that the designers have aimed for minimal locking. So the process goes roughly like this:

  1. Take a lock, check if the key is present, release the lock
  2. If the key was not present, call the Func producing the value
  3. Take a lock, check if the key is present and, if it’s not, insert the key and value

This means that if two parallel calls - A and B - came in, A could see that the key is not there, and while A is busy producing a value, B checks and also finds that the key is not there. So B also moves along to produce the value. Then A will have the value ready, check and find that the key is still not present and insert the key and value. Then B also gets the value ready, and goes to check the key only to find that now it’s there. So B throws away its value and GetOrAdd will return the value inserted by A.

As you see, the state of the dictionary itself is safe; only one value is inserted for each key, but there are side effects. So I wanted to solve this so that the task would be started only if it also inserted in the dictionary. I also found this to be an interesting case for some TDD exercise, since it offers a bit of a challenge when it comes to writing a test that would provoke the problem.

In order to test this, my thoughts went something like this:

  • First, I want to create a test where I can observe the behavior that the value factory method is invoked twice for the same key. The purpose of this test would be to prove the problem, and to prove that we can create the problematic state in code.
  • Then, I want to create another test that will expect that the value factory is invoked only once for each key. The purpose of this test is to prove the solution.

The first task was to write a test the would guarantee that this race condition occurred. In order to achieve that I would have to have some code that would call GetOrAdd with a value factory that would wait before returning its value, until it was told to continue. That way I can make two concurrent calls, wait until I know that both are inside the value factory, in parallel. When that happens, I have proven he problem. This is what I came up with:

[Test]
public void GetOrAdd_ValueFactoryCalledTwiceForSameKey()
{
    var valueFactoryWaitHandles = new[]
    {
        new ManualResetEvent(false),
        new ManualResetEvent(false)
    };

    var factoryReleaseWaitHandle = new ManualResetEvent(false);

    int waitCount = 0;

    // This value factory method will called twice, each time
    // signaling one of the factory wait handles, and then waiting
    // for the factory release wait handle to be signaled before
    // returning the value.
    Func<int, int> valueFactory = number =>
    {
        int index = Interlocked.Increment(ref waitCount) - 1;
        valueFactoryWaitHandles[index].Set();
        factoryReleaseWaitHandle.WaitOne();
        return number;
    };

    int key = 42;
    var dictionary = new ConcurrentDictionary<int, int>();

    // Start the first task that will attempt to add a value
    // using the value factory (that will wait for a signal before
    // returning the value).
    Task task1 = Task.Factory.StartNew(() =>
    {
        dictionary.GetOrAdd(key, valueFactory);
    });

    // Start the second task
    Task task2 = Task.Factory.StartNew(() =>
    {
        dictionary.GetOrAdd(key, valueFactory);
    });

    // Wait for the value factory wait handles to be signaled
    foreach (ManualResetEvent mre in valueFactoryWaitHandles)
    {
        mre.WaitOne();
    }

    // Signal the factory release handle...
    factoryReleaseWaitHandle.Set();

    // ...and wait for the tasks to finish
    task1.Wait();
    task2.Wait();

    // Verify that the factory was called twice, but the value
    // inserted only once.
    Assert.AreEqual(2, waitCount);
    Assert.AreEqual(1, dictionary.Count);
}

There, now I had a reliable way of producing the problem. This code clearly points out two things;

  1. The value factory method is invoked twice for the same key.
  2. The dictionary contains only one value afterwards.

That was the first step. Now on to...

The Solution

One prerequisite is that I could of course not alter he behavior of the ConcurrentDictionary as such, but instead needed to focus on how to handle the side effects. I needed to find a way to allow for the value factory to execute, but push the side effects forward until after the value has been inserted into the dictionary. As already mentioned; only one value for each key is inserted into the dictionary, even if the value factory is called several times. Sounds like a job for Lazy<T>, right?

Consider these two cases:

// case A
Task task = Task.Factory.StartNew(() => DoStuff());

// case B
Lazy<Task> lazyTask = new Lazy<Task>(() => Task.Factory.StartNew(() => DoStuff()));
Task task = lazyTask.Value;
        

Both cases will produce a task that is started, but in case B, the task is not produced and started until we access the Value property of lazyTask. That's nice, since it means that we can set up everything we need around producing the task, but not actually create it and start it until we say so.

This means that if we create two identical Lazy<Task> objects, but fetch the Value from just one of them, only one of the tasks will be created and started. So, by changing our ConcurrentDictionary<int, Task<int>> into a ConcurrentDictionary<int, Lazy<Task<int>>> we shield ourselves from he side effects caused by the GetOrAdd value factory to be invoked several times. The only thing that happens is that we create a bunch of Lazy<Task> objects, but only one of them will find its way into the dictionary.

Since GetOrAdd will return either the already present object, or the one that is inserted as a result of he call, all calls to GetOrAdd for a given key will return the same Lazy<Task> instance.

As often when I want to solve a situation like this, I want to find a solution that will require as little changes as possible in the code. In this case I decided to make an extension method. I started from the first test, and tried to make minimal changes for a new test that would verify the behavior where the task-producing method was invoked only once:

[Test]
public void LazyGetOrAdd_ValueFactoryCalledOnceForSameKey()
{
    ManualResetEvent valueFactoryWaitHandle = new ManualResetEvent(false);

    var factoryReleaseWaitHandle = new ManualResetEvent(false);

    int waitCount = 0;
    Func<int, int> valueFactory = number =>
    {
        Interlocked.Increment(ref waitCount);
        valueFactoryWaitHandle.Set();
        factoryReleaseWaitHandle.WaitOne();
        return number;
    };

    int key = 42;
    var dictionary = new ConcurrentDictionary<int, Lazy<int>>();

    Task task1 = Task.Factory.StartNew(() =>
    {
        dictionary.LazyGetOrAdd(key, valueFactory);
    });
    valueFactoryWaitHandle.WaitOne();

    Task task2 = Task.Factory.StartNew(() =>
    {
        dictionary.LazyGetOrAdd(key, valueFactory);
    });

    factoryReleaseWaitHandle.Set();

    task1.Wait();
    task2.Wait();

    Assert.AreEqual(1, waitCount);
    Assert.AreEqual(1, dictionary.Count);
}

As you can see, I chose to call the extension method LazyGetOrAdd, and here is how I implemented it:

public static class ConcurrentDictionaryExtensions
{
    public static TValue LazyGetOrAdd<TKey, TValue>(
        this ConcurrentDictionary<TKey, Lazy<TValue>> dictionary,
        TKey key,
        Func<TKey, TValue> valueFactory)
    {
        if (dictionary == null) throw new ArgumentNullException("dictionary");
        var result = dictionary.GetOrAdd(key, new Lazy<TValue>(() => valueFactory(key)));
        return result.Value;
    }
}

kick it on DotNetKicks.com


I am working for a great consultancy company called Diversify, located in Sweden. We are hiring skilled .NET developers. If you are interested, don't hesitate to get in touch with me.

Just as the community got used to using using...

I think that the using statement in C# is a really nice invention. It’s an excellent syntactic sugar for handling IDisposables in a correct fashion. I get the impression that it took a while for the community to make it part of their daily routine to use it and now, as we are coming there, there is a shift towards asynchronous programming that may render the using block useless (or at least temporarily so, I hope to see C# 5 handling this in conjunction with the await keyword).

Recently I ran into a situation where the asynchronous approach made the using block less ideal. I still like the simplicity of it, so I started thinking about creating a pattern that would only mean a minor shift away from it; an asynchronous using block. This pattern should ideally be close enough to a regular using block so that you could make some sort of (probably regex-based) search replace approach for moving to the asynchronous version.

This blog post is also written in a way so that it follows the thought process that I went through when making the code.

Executive summary

If you don’t want to wade through the whole thought process of creating the asynchronous using approach along with tests, skip ahead to the solution.

Let’s start from the beginning

As a starting point, let’s say that you a class that can save its contents to a Stream, and that you have some code doing that, nicely wrapped in a using block:

using (Stream stream = File.OpenWrite(@”\\slowserver\share\file.txt”))
{
    someClass.Save(stream);
}

...and then you figure that "nah, blocking this thread for that save... on that slow server… no thanks", and as it happens there is an asynchronous version of the method returning a Task:

using (Stream stream = File.OpenWrite(@”\\slowserver\share\file.txt”))
{
    // Disclaimer: in real code you would want to get hold of that Task, observing
    // any errors on it and handle them. This is omitted from the code samples for
    // the sake of focusing on the topic at hand.
    someClass.SaveAsync(stream);
}

And now you have a bug instead. You create a Stream, pass it to the asynchronous method and then immediately dispose the stream. When the save method comes around to writing to the Stream, it's is quite likely already disposed, and you will have an exception.

I imagined that rewriting the code to work with Task but without using blocks could look like this:

Stream stream = File.OpenWrite(@”\\slowserver\share\file.txt”);

someClass.SaveAsync(stream)
    .ContinueWith(task => 
    {
        if (stream != null)
        {
            stream.Dispose();
        }
    });

Simply put, this code consists of three things:

  1. Acquire the IDisposable resource
  2. Perform some action that uses that resource
  3. Dispose the resource

The goal was to encapsulate these steps into a reusable form.

Setting the stage

First I needed to figure out how to test this. The first test I wanted to write was one that used a regular using block, and that waited for the task to finish within the block. The reason was that this is a known and simple scenario where I knew the expected outcome.

[Test]
public void NormalUsingBlock_WaitForTask()
{
    var instance = new Disposable();
    using (instance)
    {
        Task.Factory.StartNew(() =>
        {
            if (instance.IsDisposed)
            {
                throw new ObjectDisposedException("The Disposable is already disposed.");
            }
        }).Wait();
    }
    Assert.IsTrue(instance.IsDisposed);
}

This is the bare minimum that I needed for the test: a class that implements IDisposable that contains a property indicating whether it’s disposed or not, and a task using that resource. If the resource is disposed before the tasks executes, an exception is thrown. Finally I verify that the resource has indeed become disposed.

The implementation of the Disposable class is the simplest possible:

public class Disposable : IDisposable
{
    public void Dispose()
    {
        IsDisposed = true;
    }

    public bool IsDisposed { get; private set; }
}

There, with that in place the first test passed as it should. Time for the next test. Now I wanted to create a scenario where the test consistently would fail if not waiting for the task within the using block; a test that would guarantee that the resource is disposed before the task tries to use it. This could probably be achieved by putting a Thread.Sleep inside the task, before checking the IsDisposed property, but Thread.Sleep is a thin ice to walk on. It can give you a reasonable chance that Dispose is invoked while sleeping, but there is no such guarantee. So I decided to use a wait handle instead, so that I can signal things in a deterministic way. I also decided to use an event to get notified when the object was disposed.

[Test]
public void NormalUsingBlock_AsyncFails()
{
    // arrange
    var instance = new Disposable();
    ManualResetEvent mre = new ManualResetEvent(false);
    EventHandler disposedHandler = (s, e) => mre.Set();
    instance.Disposed += disposedHandler;

    // act
    Task task;
    using (instance)
    {
        task = Task.Factory.StartNew(() =>
        {
            mre.WaitOne();
            if (instance.IsDisposed)
            {
                throw new ObjectDisposedException("The Disposable is already disposed.");
            }
        });
    }

    // assert
    Assert.Throws<AggregateException>(() => task.Wait());

    // clean up
    instance.Disposed -= disposedHandler;
}

For this to work I needed to add the event code to the Disposable class, and raise the event when Dispose was invoked:

public class Disposable : IDisposable
{
    public event EventHandler Disposed;

    protected void OnDisposed(EventArgs e)
    {
        EventHandler handler = Disposed;
        if (handler != null) handler(this, e);
    }

    public void Dispose()
    {
        IsDisposed = true;
        OnDisposed(EventArgs.Empty);
    }

    public bool IsDisposed { get; private set; }
}

Now I was in a position where I could verify that a regular using block would dispose my resource as expected, and also that a regular using block could dispose my resource before the task was finished, if I didn’t wait for the task inside the block. Perfect, now I had the tools to create the asynchronous using functionality.

Making it work

I realized at this point that I would needed to write a few different tests to make sure things work as I wanted them to. I also realized setting up the tests will be quite similar for each test. Since I am not a huge fan of copy/pasting large portions of code that does the same thing, I decided to encapsulate the task creation into a method:

private static Task GetTask(Disposable disposable, WaitHandle waitHandle = null)
{
    return Task.Factory.StartNew(() =>
    {
        if (waitHandle != null)
        {
            // Wait for a signal. This enables us to wait in a deterministic
            // way before checking the disposed state.
            waitHandle.WaitOne();
        }

        if (disposable.IsDisposed)
        {
            throw new ObjectDisposedException("The Disposable is already disposed.");
        }
    });
}

There, now that I had a disposable resource and an asynchronous consumer, I could write a test for an asynchronous approach to using disposable resources.

As mentioned before, there are three steps involved; acquiring the disposable resource, invoking some code that uses the resource and finally disposing the resource. Disposing the resource is done in the exact same way regardless of what resource it is. This is also reflected by the regular using block; you as a developer never supply any code for that part. The other two however must be supplied by the developer.

With that in mind, I thought out the following approach:

[Test]
public void Using_WithTask()
{
    // act
    var task = Async.Using(() => new Disposable(),
        disposable => 
        {
            return GetTask(disposable);
        });
    task.Wait();

    // assert
    Assert.IsFalse(task.IsFaulted);
}

I imagined making an Async class (for functionality facilitating some async headaches), containing a Using method that takes two parameters; a Func that produces a disposable resource, and a Func taking such a resource as input and returning a task. Since I didn’t want to be forced to unnecessary type casting, I decided to make the method generic.

Do you see the similarity of this code construction, compared to the regular using block? First we have a statement that will produce an IDisposable object of some kind, then we have a code block where we can use that object, and in this case we call the variable holding the reference to that object disposable. We use it for whatever it’s needed for, and then we return a Task (so that we can chain ContinueWith calls on it, check the result, observe exceptions and so on).

By refactoring the code sample from above (that showed using a disposable resource with tasks, but without the help of any syntactic sugar or helper methods), I came to this implementation:

public static Task Using<T>(
    Func<T> disposableAcquisition, Func<T, Task> taskFunc)
    where T : IDisposable
{
    T instance = disposableAcquisition();

    return taskFunc(instance)
        .ContinueWith(task =>
        {
            if (!ReferenceEquals(instance, null))
            {
                instance.Dispose();
            }
            return task;
        });
}

…and the test passed! There it was, the first incarnation of the async using method.

My next step would be to create a version of the async using block for when I would want to execute any piece of code inside an asynchronous using block, but that where the code does not necessarily return a Task object. It could be that you just want to push some work off the UI thread to keep the UI responsive, for instance.

As always, test comes first. By now I realized that the structure of the following tests would be quite similar to the first one, in terms of necessary setups and such, so next step was to move some setup and teardown work to separate methods, moving some noise away from the tests:

[TestFixture]
public class AsyncTests
{
    private Disposable disposableInstance;
    private ManualResetEvent manualResetEvent;

    [SetUp]
    public void Setup()
    {
        disposableInstance = new Disposable();
        manualResetEvent = new ManualResetEvent(false);
        disposableInstance.Disposed += DisposedHandler;
    }

    private void DisposedHandler(object s, EventArgs e)
    {
        manualResetEvent.Set();
    }

    // the tests go here (removed for brevity)
}

Now the disposable class instance was created with all necessary wiring set up automatically before each tests was executed, so that code did not need to reside inside each test. I like how that makes the test code more focused on its purpose. So with that in place, I could make a simple test to make sure that I could execute code that does not involve a Task in the same sort of asynchronous manner:

[Test]
public void Using_WithAction()
{
    // act
    var task = Async.Using(() => disposableInstance,
        disposable =>
        {
            // wait for the wait handle to be signaled
            manualResetEvent.WaitOne();

            if (disposable.IsDisposed)
            {
                throw new ObjectDisposedException("The Disposable is already disposed.");
            }
        });

    manualResetEvent.Set();
    task.Wait();

    // assert
    Assert.IsFalse(task.IsFaulted);
}

Same approach as before, only this time without a Task. The code will throw an exception if the disposable object is disposed prior to the wait handle being signaled. The wait handle is signaled after the Async.Using method call returns. Finally the test verifies that the disposable resource is properly disposed, and that the resulting Task does not fail.

"Wait a minute..., didn't you just say that this test scenario did not involve any Task!?"  Yes I did, and I meant it ;-) The code that executes asynchronously within the block does not use or return any Task, but the construct itself, the Async.Using method, wraps the whole thing in a new Task that is returned so that your code can wait for it, chain other operations to follow on it, observe exceptions and so on. Let's looks at the implementation and it will be more clear:

public static Task Using<T>(
    Func<T> disposableAcquisition, Action<T> action)
    where T : IDisposable
{
    T disposable = disposableAcquisition();

    return Task.Factory.StartNew(() => action(disposable))
        .ContinueWith(task =>
        {
            if (!ReferenceEquals(disposable, null))
            {
                disposable.Dispose();
            }
            return task;
        });
}

As you can see, it's very similar to the one we created first, but it creates a new Task that invokes the Action<T> delegate that is passed into the method, and returns that Task object.

At this point, the Async class started to fulfill the needs that I had, so I didn't do much more work on it, but there are of course a lot more that code be done with it.

The final Async class

Here is the the "full" Async class, should you want to use it. I say "full", since it is in no way complete; there are many overloads that you could wish for, supporting Action and Func delegates with various number of type arguments, for instance.

You can also grab a full Visual Studio solution (containing both the class and some tests) from my BitBucket repository.

/*
 * This file is created by Fredrik Mörk, twitter.com/fmork
 *
 * It comes without any warranty of any kind. Use it at your own risk.
 * But feel free to do so.
 */

using System;
using System.Threading.Tasks;

namespace Alcedo.AsyncUsing
{
    /// <summary>
    /// Contains functionality for asynchronous operations.
    /// </summary>
    public static class Async
    {
        /// <summary>
        /// Emulates a using block with asynchronous support.
        /// </summary>
        /// <typeparam name="T">A type that implements <see cref="IDisposable"/></typeparam>
        /// <param name="disposableAcquisition">A <see cref="Func{TResult}"/> that gets
        /// an object that implements <see cref="IDisposable"/>.</param>
        /// <param name="action">The action to perform asynchronously.</param>
        public static Task Using<T>(
            Func<T> disposableAcquisition, Action<T> action)
            where T : IDisposable
        {
            T disposable = disposableAcquisition();

            return Task.Factory.StartNew(() => action(disposable))
                .ContinueWith(task =>
                {
                    if (!ReferenceEquals(disposable, null))
                    {
                        disposable.Dispose();
                    }
                    return task;
                });
        }

        /// <summary>
        /// Emulates a using block with asynchronous support.
        /// </summary>
        /// <typeparam name="T">A type that implements <see cref="IDisposable"/></typeparam>
        /// <param name="disposableAcquisition">A <see cref="Func{TResult}"/> that gets
        /// an object that implements <see cref="IDisposable"/>.</param>
        /// <param name="taskFunc">A <see cref="Func{T,Task}"/> that
        /// uses the <see cref="IDisposable"/> object.</param>
        /// <returns></returns>
        public static Task Using<T>(
            Func<T> disposableAcquisition, Func<T, Task> taskFunc)
            where T : IDisposable
        {
            T instance = disposableAcquisition();

            return taskFunc(instance)
                .ContinueWith(task =>
                {
                    if (!ReferenceEquals(instance, null))
                    {
                        instance.Dispose();
                    }
                    return task;
                });
        }

        /// <summary>
        /// Emulates a using block with asynchronous support for a task that returns a result.
        /// </summary>
        /// <typeparam name="T">A type that implements <see cref="IDisposable"/></typeparam>
        /// <typeparam name="TResult">The type or the result produced by the task.</typeparam>
        /// <param name="disposableAcquisition">A <see cref="Func{TResult}"/> that gets
        /// an object that implements <see cref="IDisposable"/>.</param>
        /// <param name="taskFunc">A <see cref="Func{T,Task}"/> that uses
        /// the <see cref="IDisposable"/> object.</param>
        public static Task<TResult> Using<T, TResult>(
            Func<T> disposableAcquisition, Func<T, Task<TResult>> taskFunc)
            where T : IDisposable
        {
            T instance = disposableAcquisition();

            return taskFunc(instance)
                .ContinueWith(task =>
                {
                    if (!ReferenceEquals(instance, null))
                    {
                        instance.Dispose();
                    }
                    return task.Result;
                });
        }
    }
}

kick it on DotNetKicks.com


I am working for a great consultancy company called Diversify, located in Sweden. We are hiring skilled .NET developers. If you are interested, don't hesitate to get in touch with me.