Skip to main content

Future Delegate (C#)

Here's a tool I've recently added to my personal library: Future Delegate

A Future Delegate is essentially an encapsulation of an asynchronous delegate inside a generic class which handles all the details of calling and waiting for the delegate to return. It works like this:

1. Write a method to do some work asynchronously.
2. Create a Future and pass in a delegate to your method.
3. Do other stuff...
4. Call Future.Value whenever you need to result of the operation.

The Future class will store the result if the operation completed before you called the Value property. If the operation is not complete when you call the Value property, the call will block until the operation completes. This is a very hassle-free way to deploy jobs on many threads.

Here is an example of how it is used:


    private int Worker(object state)
    {
        int x = Convert.ToInt32(state)
        for(int i=0; i<x; i++)
        {
            Thread.Sleep(1000);
        }
        return x;
    }

    public int MainMethod()
    {
        FutureDelegate<int> workerDelegate = new FutureDelegate<int>(Worker);
        Future worker = new Future<int>(workerDelegate, 5);
    
        // Do other stuff....

        return worker.Value;
    }

Here's an example of how to implement Future:


    public delegate R FutureDelegate<R>(object state);

    public class Future<T>
    {
        private readonly FutureDelegate<T> Del;
        private readonly IAsyncResult Result;
        private T PValue;

        public Future(FutureDelegate<T> del, object state)
        {
            Del = del;
            Result = del.BeginInvoke(state, new AsyncCallback(Done), null);
        }
        
        private T Value
        {
            get
            {
                lock (Result)
                {
                    if (!Result.IsCompleted)
                        Monitor.Wait(Result);

                    return PValue;
                }
            }
        }
        
        public static implicit operator T(Future<T> f)
        {
            return f.Value;
        }

        private void Done(IAsyncResult r)
        {
            // Result can be null is delegate completed synchronously.
            if (Result != null)
                Monitor.Enter(Result);

            PValue = Del.EndInvoke(Result);
            Monitor.Pulse(Result);

            if (Result != null)
                Monitor.Exit(Result);
        }
    }

Implementation

I should point out that I have found other Future implementations on the web which are not 100% thread-safe and can expose race conditions under certain circumstances. This example has been tested under high load conditions to be completely solid.

Actually...

...this code should throw an exception rather fast:

for (int i = 0; i < 10000; i++)
{
Future test = new Future(dummy => "a", null);
string res = (string)test;
Console.Write(res);
}

This implementation does not seem to have that problem: Not Impossible: The Future Revealed.

(As a side note, I also prefer to have the Value property public (you can then have an IFuture<T> interface, for example), but that's just a preference.)

Interesting

I'll admit, that's not a use case I considered. Most people are parallelizing a handful of tasks in proportion to the number of cores they have at their disposal. If you're in a situation where you have thousands of non-trivial (>10ms) tasks you need run in parallel, you should probably not cut-and-paste code off the web to do it. ;)

Nice work

Good work! FYI your Value property is marked as private

Thanks!

This implementation returns the value through the implicit cast operator. It's a subtle point and I can see an argument to use the Value property instead (for clarity).