ExtensionMethod.NET Home of 880 C#, Visual Basic, F# and Javascript extension methods

AwaitableTaskEnumerableExtensions

Awaitable fluent extensions for enumerables of task

Source

/// <summary>
///     Linq extension to be able to fluently wait for all of <see cref="IEnumerable{T}" /> of <see cref="Task" /> just
///     like <see cref="Task.WhenAll(System.Threading.Tasks.Task[])" />.
/// </summary>
/// <param name="tasks">The tasks.</param>
/// <returns>An awaitable task</returns>
/// <remarks></remarks>
/// <example>
///     var something = await foos.Select(foo => BarAsync(foo)).WhenAll();
/// </example>
/// <exception cref="System.ArgumentNullException"></exception>
/// <exception cref="System.ArgumentException"></exception>
public static Task WhenAll(this IEnumerable<Task> tasks)
{
    var enumeratedTasks = tasks as Task[] ?? tasks?.ToArray();

    return Task.WhenAll(enumeratedTasks);
}

/// <summary>
///     Linq extension to be able to fluently wait for any of <see cref="IEnumerable{T}" /> of <see cref="Task" /> just
///     like <see cref="Task.WhenAll(System.Threading.Tasks.Task[])" />.
/// </summary>
/// <param name="tasks">The tasks.</param>
/// <returns>An awaitable task</returns>
/// <remarks></remarks>
/// <example>
///     var something = await foos.Select(foo => BarAsync(foo)).WhenAll();
/// </example>
/// <exception cref="System.ArgumentNullException"></exception>
/// <exception cref="System.ArgumentException"></exception>
public static Task WhenAny(this IEnumerable<Task> tasks)
{
    var enumeratedTasks = tasks as Task[] ?? tasks.ToArray();

    return Task.WhenAny(enumeratedTasks);
}

/// <summary>
///     Linq extension to be able to fluently wait for all of <see cref="IEnumerable{T}" /> of <see cref="Task" /> just
///     like <see cref="Task.WhenAll(System.Threading.Tasks.Task{TResult}[])" />.
/// </summary>
/// <param name="tasks">The tasks.</param>
/// <returns>An awaitable task</returns>
/// <remarks></remarks>
/// <example>
///     var bars = await foos.Select(foo => BarAsync(foo)).WhenAll();
/// </example>
/// <exception cref="System.ArgumentNullException"></exception>
/// <exception cref="System.ArgumentException"></exception>
public static async Task<IEnumerable<TResult>> WhenAll<TResult>(this IEnumerable<Task<TResult>> tasks)
{
    var enumeratedTasks = tasks as Task<TResult>[] ?? tasks.ToArray();

    var result = await Task.WhenAll(enumeratedTasks);
    return result;
}

/// <summary>
///     Linq extension to be able to fluently wait for all of <see cref="IEnumerable{T}" /> of <see cref="Task" /> just
///     like <see cref="Task.WhenAny(System.Threading.Tasks.Task{TResult}[])" />.
/// </summary>
/// <param name="tasks">The tasks.</param>
/// <returns>An awaitable task</returns>
/// <remarks></remarks>
/// <example>
///     var bar = await foos.Select(foo => BarAsync(foo)).WhenAll();
/// </example>
/// <exception cref="System.ArgumentNullException"></exception>
/// <exception cref="System.ArgumentException"></exception>
public static async Task<TResult> WhenAny<TResult>(this IEnumerable<Task<TResult>> tasks)
{
    var enumeratedTasks = tasks as Task<TResult>[] ?? tasks.ToArray();

    var result = await await Task.WhenAny(enumeratedTasks);
    return result;
}

Example

private static void Main(string[] args)
{
    FooBarAsync().Wait();
}

private static IEnumerable<int> foos = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

public static async Task FooBarAsync()
{
    var watch = new Stopwatch();
    watch.Start();

    await foos.Select(foo => BarAsync(foo)).WhenAll();
    var results = await foos.Select(foo => BarAsync(foo)).WhenAll();

    watch.Stop();
    Console.WriteLine("WhenAll -->:" + watch.Elapsed);
    watch.Reset();

    watch.Start();

    await foos.Select(foo => BarAsync(foo)).WhenAny();
    var result = await foos.Select(foo => BarAsync(foo)).WhenAny();

    watch.Stop();
    Console.WriteLine("WhenAny -->:" + watch.Elapsed);
    
    Console.ReadKey();
}

public static async Task<int> BarAsync(int something)
{
    await Task.Delay(new Random((int)DateTime.Now.Ticks).Next(100, 1500));

    return something;
}

Author: Aleix Domènech

Submitted on: 6 apr. 2017

Language: C#

Type: IEnumerable<Task>

Views: 3658