What should I do to use Task<T> in .NET 2.0?

I know you said you dont want to rewrite Task, but you can actually create something fairly simple using closures, which behaves somewhat like a Task object. This is what I use:

    public delegate R AsyncTask<R>();

    public static AsyncTask<R> BeginTask<R>(AsyncTask<R> function)
    {
        R retv = default(R);
        bool completed = false;

        object sync = new object();

        IAsyncResult asyncResult = function.BeginInvoke(
                iAsyncResult =>
                {
                    lock (sync)
                    {
                        completed = true;
                        retv = function.EndInvoke(iAsyncResult);
                        Monitor.Pulse(sync); 
                    }
                }, null);

        return delegate
        {
            lock (sync)
            {
                if (!completed)               
                {
                    Monitor.Wait(sync); 
                }
                return retv;
            }
        };
    }

Its a function that calls BeginInvoke() on the delegate you pass in, and returns a function that when called blocks and waits for the result of the function passed in. You'd have to create overloads of this function for different method signatures, of course.

One way to go, you can tweak this to your needs, and add other behaviors too like Continuations, etc. The key is to use closures and anonymous delegates. Should work in .NET 2.0.

EDIT - Here is how you would use it:

    public static string HelloWorld()
    {
        return "Hello World!"; 
    }

    static void Main(string[] args)
    {
        var task = BeginTask(HelloWorld); // non-blocking call

        string result = task(); // block and wait

    }

You will have to use System.Threading.Thread class, you can get the Task class for .net 3.5 but not for .net 2.

Sorry