I have a method with the following structure:
public Task InitializeAsync()
{
var taskCompletionSource = new TaskCompletionSource<bool>();
Task firstTask = ...;
// secondTask calls taskCompletionSource.TrySetResult(true) once it considers itself "done"
Task secondTask = firstTask.ContinueWith(..., TaskContinuationOptions.OnlyOnRanToCompletion);
Action<TasK> errorContinuation = x =>
{
taskCompletionSource.SetException(e.Exception);
};
firstTask.ContinueWith(errorContinuation, TaskContinuationOptions.OnlyOnFaulted);
secondTask.ContinueWith(errorContinuation, TaskContinuationOptions.OnlyOnFaulted);
return taskCompletionSource.Task;
}
Importantly:
InitializeAsync isn't considered complete until the secondTask decides sosecondTask only runs if firstTask is successfulfirstTask or secondTask causes the overall task to failWhat I'm wondering is whether there's a cleaner, simpler way to express this whilst achieving the same functionality. I'm using .NET 4.0 but am interested in whether 4.5 makes this easier, too.
For .NET 4.0, I used an idea from this blog article to chain tasks like you describe. In particular, look at the section titled Then. Not that his version expects you to pass in a function that returns a task instead of just passing a method like you would to ContinueWith
As an aside, Then gets you pretty close to the SelectMany you would need to be able to chain the tasks via LINQ from clauses. I mention this mostly as a syntax option until async/await in .NET 4.5, though I don't actually use that myself.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With