Futures in IJW Framework (C#)
Sunday 2 August 2009 - Filed under Code
I’m writing some stuff involving various map tile servers out on the internet, which are internet-slow at responding. To avoid cluttering up all my other code with asynchronous junk, I’ve implemented Futures in C#, like so:
namespace IjwFramework.Types { public class Future<T> { Func<T> f; IAsyncResult async; T value; bool hasValue = false; public Future(Func<T> f) { this.f = f;async = f.BeginInvoke(null, null); } T Value { get { if (!hasValue) { if (!async.IsCompleted) async.AsyncWaitHandle.WaitOne(); value = f.EndInvoke(async); hasValue = true; } return value; } } public bool HasValue { get { return hasValue; } } public static implicit operator T(Future<T> f) {return f.Value; } } public static class Future { public static Future<T> New<T>(Func<T> f) {return new Future<T>(f); } }
The static class is just there to enable type inference – yes, it’s C++ all over again, with different rules for generic type inference on methods and typenames.
The remaining ugly part of this is what to do if the Func<T> throws – propagating that out to the unfortunate thread that calls Value might be a good idea in some cases, but in others, wrapping the return type (or indeed, letting the Func<T> do it!) in something akin to Haskell’s Maybe type might not be a bad move. Of course, there’s the issue of dropping the exception information on the floor, if you take that route though.
I’m using this technique quite a lot in my current project, so I’ll experiment with the various solutions and see if any clear winner falls out.
Until then, enjoy the exception-oblivious version!
2009-08-02 » admin