Created
March 29, 2023 10:37
-
-
Save doeringp/a416768ab19ac8a8877569a7ba61db5f to your computer and use it in GitHub Desktop.
Extends Task.WhenAny to return only a task if a condition matches
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
public static class AsyncExtensions | |
{ | |
/// <summary> | |
/// Creates a task that will complete when any of the tasks have completed and the task result matches the <paramref name="condition"/>. | |
/// </summary> | |
/// <typeparam name="TResult">The result type produced by each task in the list.</typeparam> | |
/// <param name="tasks">The tasks to wait on for completion.</param> | |
/// <param name="condition">The condition the completed task should match in order to be returned.</param> | |
/// <returns> | |
/// A task that represents the completion of one of the supplied tasks. | |
/// The return Task's Result is the result of the first task that completed and matched the <paramref name="condition"/>. | |
/// </returns> | |
/// <exception cref="System.ArgumentNullException"> | |
/// The <paramref name="tasks"/> or <paramref name="condition"/> argument was null. | |
/// </exception> | |
/// <exception cref="System.ArgumentException"> | |
/// The <paramref name="tasks"/> collection contained a null task, or was empty. | |
/// </exception> | |
public static async Task<TResult?> WhenAny<TResult>(this ICollection<Task<TResult>> tasks, Predicate<TResult> condition) | |
{ | |
ArgumentNullException.ThrowIfNull(tasks); | |
ArgumentNullException.ThrowIfNull(condition); | |
if (!tasks.Any()) | |
{ | |
throw new ArgumentException("The tasks list was empty.", nameof(tasks)); | |
} | |
while (tasks.Count > 0) | |
{ | |
var task = await Task.WhenAny(tasks); | |
TResult result = await task; | |
if (condition(result)) | |
{ | |
return result; | |
} | |
tasks.Remove(task); | |
} | |
return default; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment