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