var t1 = DoFooAsync(obj); var t2 = DoBarAsync(obj); var t = await WhenAnySuccessOrAllFail(t1, t2); async Task WhenAnySuccessOrAllFail(params Task[] tasks) { var remaining = new List<Task>(tasks); while (remaining.Count > 0) { var t = await Task.WhenAny(remaining); if (t.IsCompletedSuccessfully) { // Successful so return it return t; } // It failed, remove it from the remaining tasks to process remaining.Remove(t); } // Both failed (will bubble an aggregate exception) return await Task.WhenAll(tasks); }