Created
November 6, 2015 14:56
-
-
Save icalvo/a740c4cd0697b6765ea1 to your computer and use it in GitHub Desktop.
Waiting for all tasks but cancel them all the moment one of them fails.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[TestClass] | |
public class TaskTests | |
{ | |
[TestMethod] | |
public async Task Trololo() | |
{ | |
Console.WriteLine("Starting"); | |
var tokenSource = new CancellationTokenSource(); | |
var token = tokenSource.Token; | |
Task task1 = Task.Run(async () => | |
{ | |
await Task.Delay(1000, token); | |
Console.WriteLine("Finished task 1"); | |
}, token); | |
Task task2 = Task.Run(async () => | |
{ | |
await Task.Delay(2000, token); | |
Console.WriteLine("Task 2 throwing..."); | |
throw new Exception(); | |
}, token); | |
Task task3 = Task.Run(async () => | |
{ | |
await Task.Delay(4000, token); | |
if (token.IsCancellationRequested) | |
{ | |
return; | |
} | |
Console.WriteLine("Finished task 3 (BAD)"); | |
}, token); | |
try | |
{ | |
await WaitAllThrowingAtFirstFail(new[] { task1, task2, task3 }); | |
Console.WriteLine("Finished all tasks"); | |
} | |
catch | |
{ | |
tokenSource.Cancel(); | |
Console.WriteLine("One task failed"); | |
} | |
await Task.Delay(6000); | |
} | |
private async Task WaitAllThrowingAtFirstFail(IEnumerable<Task> tasks) | |
{ | |
List<Task> taskList = tasks.ToList(); | |
while (taskList.Count > 0) | |
{ | |
Task firstFinishedTask = await Task.WhenAny(taskList); | |
if (firstFinishedTask.IsFaulted) | |
{ | |
throw new Exception(); | |
} | |
taskList.Remove(firstFinishedTask); | |
await firstFinishedTask; | |
} | |
} | |
private async Task<IEnumerable<T>> WaitAllThrowingAtFirstFail<T>(IEnumerable<Task<T>> tasks) | |
{ | |
List<Task<T>> taskList = tasks.ToList(); | |
List<T> results = new List<T>(); | |
while (taskList.Count > 0) | |
{ | |
Task<T> firstFinishedTask = await Task.WhenAny(taskList); | |
if (firstFinishedTask.IsFaulted) | |
{ | |
throw new Exception(); | |
} | |
taskList.Remove(firstFinishedTask); | |
if (firstFinishedTask.IsCompleted) | |
{ | |
results.Add(firstFinishedTask.Result); | |
} | |
} | |
return results; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment