async / await continuation

async-await, asynchronous, c#

Solution

I would not mix `ContinueWith` and `await` and rather use an `async` lambda directly:

protected async Task  DoStuffAsync()
{
    SomeThing thing = new SomeThing { ID = 5 };
    SomeRepository rep = new SomeRepository();

    // We need to run all three Get... methods in parallel
    // As soon as a Get... method completes we need to save the result to the correct property on thing and call the Save... method .

    Func<Task<X>> getRedFunc = async() =>
    {
        var result = await rep.GetRedAsync();
        thing.Color1 = result;
        await rep.SaveRedAsync(thing);
        return result;
    };

    var getRed = getRedFunc();

    var getBlue = rep.GetBlueAsync();
    var getGreen = rep.GetGreenAsync();

    await Task.WhenAll(getRed, getBlue, getGreen);
}

Also, don't use `async void` methods for anything but event handlers. You won't be able to observe the completion of a method like this or handle exceptions possibly thrown inside it.

Problem

In the code below I need to execute the three Get... methods in parallel. When a Get... method completes I need to immediately call the Save... method. Note Save... takes thing as a parameter. All Get and Save methods must complete before DoStuffAsync returns. My guess is that I need a continuation on the Get... methods but I dont know how to construct it. ``` protected async void DoStuffAsync() { SomeThing thing = new SomeThing { ID = 5 }; SomeRepository rep = new SomeRepository(); // We need to run all three Get... methods in parallel // As soon as a Get... method completes we need to save the result to the correct property on thing and call the Save... method . var getRed = rep.GetRedAsync().ContinueWith<Task<string>>(async x => { thing.Color1 = x.Result; await rep.SaveRedAsync(thing); return x; }); // does not compile var getBlue = rep.GetBlueAsync(); var getGreen = rep.GetGreenAsync(); string red = await getRed.Result; // this is not good because getBlue may finish before getRed. We want dont want to wait on getRed before calling SaveBlue await rep.SaveRedAsync(thing); var b = await getBlue; var c = await getGreen; // thing must be fully initialized before DoStuffAsync returns } public class SomeThing { public int ID { get; set; } public string Color1 { get; set; } public string Color2 { get; set; } public string Color3 { get; set; } } public class SomeRepository { public async Task<string> GetRedAsync() { return await Task.Run(() => "red"); } public async Task<string> GetBlueAsync() { return await Task.Run(() => "blue"); } public async Task<string> GetGreenAsync() { return await Task.Run(() => "green"); } public async Task SaveRedAsync(SomeThing thing) { // We need thing.ID here as well as other properties await Task.Delay(1); } public async Task SaveBlueAsync(SomeThing thing) { await Task.Delay(1); } public async Task SaveGreenAsync(SomeThing thing) { await Task.Delay(1); } } ```

Original source