Executing code asynchronously in C# gives you at least two headaches: the code becomes hard to read and a pain to unit test.
Here's one way to alleviate these pains, using a configurable singleton aptly named "Async":
Async.Execute(() => { // ... Console.WriteLine("We're running this on a background thread"); // ... etc });
That's the readability headache removed. Here's how we implement the Async class:
public class Async { private static IAsyncExecutor theAsyncExecutor; public static void Configure(IAsyncExecutor asyncExecutor) { theAsyncExecutor = asyncExecutor; } public static void Execute(Action a) { theAsyncExecutor.Execute(a); } } public interface IAsyncExecutor { void Execute(Action a); }
You need to configure Async with a concrete IAsyncExecutor. A ThreadPool implementation is one solution for Silverlight/WPF/WinForms:
public class ThreadPoolAsyncExecutor : IAsyncExecutor { public void Execute(Action a) { ThreadPool.QueueUserWorkItem(x => a()); } }
That's actually not too messy, but let's agree that "Async.Execute" is easier on the eyes than "ThreadPool.QueueUserWorkItem".
What about the testing-headache? Get instant relief by configuring Async with a fake IAsyncExecutor before you run your unittests:
public class FakeAsyncExecutor : IAsyncExecutor { public void Invoke(Action a) { a(); } }
Cheating, you say? Well, do we really need to assert that the code is being run on a background thread? More likely we just want assert that it does what it's supposed to do, regardless of which thread it runs on. But, if you indeed want to assert that the class does some task in the background, you can assert that the Execute method is being called on your fake/mock IAsyncExecutor.
Now all we need to do is learn how to reliably spell asynchrounu... asynchronus… yeah.
Hope this helps,
Andreas Hallberg
Consultant at Jayway

2 comments ↓
[...] Readable and testable asynchronous execution – Andreas Hallberg shares a simple helper class which makes writing Async code cleaner, and provides an implementation which can be easily replaced for testing to remove the async nature. [...]
Love the simplicity!
Kudos
Leave a Comment