Prior to .NET 4, one had to implement the APM model in order to expose asynchronous methods. After a couple of years, the AsyncEnumerator class came out to simplify the APM by leveraging the use of C# iterators for asynchrony. In the meantime, Microsoft developed a new model for asynchronous (and parallel) programming. Since the new model was targeting the .NET 4, code written in previous versions have to keep using the AsyncEnumerator class.
I have been using the AsyncEnumerator class since 2008 and it works great. Today we have the new Async and Await keywords in C# 5.0 (together with the many improvements in the CLR) that will ship with .NET 4.5 and the recently added support for async unit tests on version 1.9 of the xUnit.net. So, I decided to move some .NET 2.0 code using AsyncEnumerator to .NET 4.5 using Async and Await.
Below is an interface of the sample type (described in this article) exposing both synchronous and asynchronous versions of a time-consuming method:
A unit test with the AsyncEnumerator can be similar to the one shown below:
However, since xUnit.net does not support methods of type IEnumerator<int>, we need to tell xUnit.net how to execute them:
Moving to .NET 4.5 and xUnit.net 1.9 we can create an Extension Method that returns a Task in order to use both the Async and Await keywords in production code and the async unit tests feature of xUnit.net.
Now the previous unit test with the AsyncEnumerator can be rewritten as follow:
This looks very nice and clean. As it seems though, if the class contains many async unit tests they will not run in parallel.
As an example, the following 3 tests will take 3 x 5 = 15 seconds to complete:
The output from xUnit.net:
That was the part of moving the unit tests from an older version of xUnit.net (and the AsyncEnumerator) to version 1.9 of xUnit.net (with Async and Await). Apparently, things become more challenging when moving to production code where one needs to deal with stuff such is the SyncrhonizationContext.
A gist with all the source code can be found here.