How to chain independent C# tasks?

Is there any reason not to use await? For example,

async Task Sequential()
{
    await A();
    await B();
    X();
}

Assuming that you cannot use async/await as suggested in other answers (if you can, you should), there's a nifty little extension method available to cater for this scenario since the introduction of Task in .NET 4.0: System.Threading.Tasks.TaskExtensions.Unwrap. It takes in a Task<Task> (or Task<Task<TResult>>) and "flattens" it into a contiguous Task (or Task<TResult> respectively), which represents the completion of both the outer task, and the inner task.

Using that extension method your method can be rewritten as:

Task Sequential()
{
    return A()
        .ContinueWith(t => B()).Unwrap()
        .ContinueWith(t => X()); // You said X() is "non-async", so no Unwrap here.
}

The resultant Task will represent the completion of the entire sequential chain of tasks, in the expected order.

There is also the concept of "child tasks" originally devised for this very purpose in the early days of the Task Parallel Library, but it is horrendously difficult to use and requires that you have great control over how the tasks are started, which you may not have. Still, it's worth knowing about (if only for education's sake).


There's a fairly neat way to do this using Microsoft's Reactive Framework (NuGet "System.Reactive").

public Task Sequential()
{
    return
    (
        from a in Observable.FromAsync(() => A())
        from b in Observable.FromAsync(() => B())
        from c in Observable.Start(() => X())
        select c
    ).ToTask();
}

If we define the methods are this:

public Task A() { return Task.Run(() => { "A".Dump(); Thread.Sleep(1000); "A".Dump(); }); }
public Task B() { return Task.Run(() => { "B".Dump(); Thread.Sleep(1000); "B".Dump(); }); }
public void X() { "X".Dump(); Thread.Sleep(1000); "X".Dump(); }

Then running Sequential().Wait(); produces this:

A
A
B
B
X
X