Изменения в новых версиях / C# 5.0

using System;
using System.Threading.Tasks;

class Program {
    static Task<intLoadAsync(string name) {
        return Task.Run(() => name.Length);
    }

    // *** before: ***
    // work that finishes later was continued in a callback, so the steps
    // were written back to front and nested one inside another
    static void TotalOld(Action<int> done) {
        LoadAsync("first").ContinueWith(a => {
            LoadAsync("second").ContinueWith(b => {
                done(a.Result + b.Result);
            });
        });
    }

    // *** in version 5.0: ***
    // await splits the method at that point: it returns to the caller and
    // continues from here when the task is ready
    static async Task<intTotalNew() {
        int a = await LoadAsync("first");
        int b = await LoadAsync("second");
        return a + b;
    }

    static void Main() {
        TotalOld(total => Console.WriteLine(total));
        Console.WriteLine(TotalNew().Result);

        // async is not a thread: the method runs on the caller thread until
        // the first await, and no thread waits while the task is running
    }
}