Skip to content

Instantly share code, notes, and snippets.

@icalvo
Created November 6, 2015 14:56
Show Gist options
  • Save icalvo/a740c4cd0697b6765ea1 to your computer and use it in GitHub Desktop.
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.
[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