Chaining Tasks with async/await I've been trying to learn how to use the TPL for quite some time now.
Basically I'm trying to fire off a group of Tasks, wait for them to complete and then fire off another group of tasks, waiting for them to complete before firing off the tasks that update form elements on the UI Thread.

Here's what I got. I think I'm probably overcomplicating it however it does seem to work as I want it too.
Please could I have some advice on how I could simplify this based on what I want to achieve?

private async Task PrepareData()
{
    Task[] FirstTasks = new Task[] { TaskOne(), TaskTwo() };    // Do First group of Tasks
    await Task.WhenAll(FirstTasks); // Wait for First group of Tasks

    Task[] SecondTasks = new Task[] { TaskThree(), TaskFour() }; // Do Second group of Tasks
    await Task.WhenAll(SecondTasks).ContinueWith(c =&gt; // Wait for Second group of Tasks 
        {
            GuiTaskOne();
            GuiTaskTwo();
        }, TaskScheduler.FromCurrentSynchronizationContext());  // Then update the form on the UI Thread
}

private async Task TaskOne()
{
    someVariable = await Task.Run(() =&gt; DoSomething());
}

private async Task TaskTwo()
{
    someVariable = await Task.Run(() =&gt; DoSomething());
}

private async Task TaskThree()
{
    someVariable = await Task.Run(() =&gt; DoSomething());
}

private async Task TaskFour()
{
    someVariable = await Task.Run(() =&gt; DoSomething());
}

private async Task GuiTaskOne()
{
    someControl.Text = await Task.Run(() =&gt; DoSomething());
}

private async Task GuiTaskTwo()
{
    someControl.Text = await Task.Run(() =&gt; DoSomething());
}
Since await is effectively a continuation anyway, you could simplify your function to:

private async Task PrepareData()
{
    Task[] FirstTasks = new Task[] { TaskOne(), TaskTwo() };    // Do First group of Tasks
    await Task.WhenAll(FirstTasks); // Wait for First group of Tasks

    Task[] SecondTasks = new Task[] { TaskThree(), TaskFour() }; // Do Second group of Tasks
    await Task.WhenAll(SecondTasks); // Wait for Second group of Tasks 

    GuiTaskOne();
    GuiTaskTwo();
}


I also suspect you meant to await the GUI tasks too.