2020-12-28 14:34:13 -04:00
// Copyright Epic Games, Inc. All Rights Reserved.
using System ;
using System.Collections.Generic ;
using System.Linq ;
using System.Threading.Tasks ;
using System.Threading.Tasks.Dataflow ;
namespace EpicGames.Core
{
/// <summary>
/// Async equivalents for parallel methods
/// </summary>
public static class ParallelTask
{
/// <summary>
/// Execute a large number of tasks in parallel over a collection. Parallel.ForEach() method isn't generally compatible with asynchronous programming, because any
/// exceptions are thrown on the
/// </summary>
2022-03-24 16:35:00 -04:00
/// <param name="fromInclusive">The starting index</param>
/// <param name="toExclusive">The last index, exclusive</param>
/// <param name="action">Action to perform for each item in the collection</param>
2020-12-28 14:34:13 -04:00
/// <returns>Async task</returns>
2022-03-24 16:35:00 -04:00
public static Task ForAsync ( int fromInclusive , int toExclusive , Action < int > action )
2020-12-28 14:34:13 -04:00
{
2022-03-24 16:35:00 -04:00
return ForEachAsync ( Enumerable . Range ( fromInclusive , toExclusive - fromInclusive ) , action ) ;
2020-12-28 14:34:13 -04:00
}
/// <summary>
/// Execute a large number of tasks in parallel over a collection. Parallel.ForEach() method isn't generally compatible with asynchronous programming, because any
/// exceptions are thrown on the
/// </summary>
/// <typeparam name="T">The collection type</typeparam>
2022-03-24 16:35:00 -04:00
/// <param name="collection">The collection to iterate over</param>
/// <param name="action">Action to perform for each item in the collection</param>
2020-12-28 14:34:13 -04:00
/// <returns>Async task</returns>
2022-03-24 16:35:00 -04:00
public static Task ForEachAsync < T > ( IEnumerable < T > collection , Action < T > action )
2020-12-28 14:34:13 -04:00
{
2022-03-24 16:35:00 -04:00
ExecutionDataflowBlockOptions options = new ExecutionDataflowBlockOptions ( ) ;
options . MaxDegreeOfParallelism = DataflowBlockOptions . Unbounded ;
2020-12-28 14:34:13 -04:00
2022-03-24 16:35:00 -04:00
ActionBlock < T > actions = new ActionBlock < T > ( action , options ) ;
foreach ( T item in collection )
2020-12-28 14:34:13 -04:00
{
2022-03-24 16:35:00 -04:00
actions . Post ( item ) ;
2020-12-28 14:34:13 -04:00
}
2022-03-24 16:35:00 -04:00
actions . Complete ( ) ;
2020-12-28 14:34:13 -04:00
2022-03-24 16:35:00 -04:00
return actions . Completion ;
2020-12-28 14:34:13 -04:00
}
2021-04-27 22:41:48 -04:00
/// <summary>
/// Execute a large number of tasks in parallel over a collection. Parallel.ForEach() method isn't generally compatible with asynchronous programming, because any
/// exceptions are thrown on the
/// </summary>
/// <typeparam name="T">The collection type</typeparam>
2022-03-24 16:35:00 -04:00
/// <param name="collection">The collection to iterate over</param>
/// <param name="action">Action to perform for each item in the collection</param>
/// <param name="maxDegreeOfParallelism">Maximum degree of parallelism</param>
2021-04-27 22:41:48 -04:00
/// <returns>Async task</returns>
2022-03-24 16:35:00 -04:00
public static Task ForEachAsync < T > ( IEnumerable < T > collection , Func < T , Task > action , int maxDegreeOfParallelism )
2021-04-27 22:41:48 -04:00
{
2022-03-24 16:35:00 -04:00
ExecutionDataflowBlockOptions options = new ExecutionDataflowBlockOptions ( ) ;
options . MaxDegreeOfParallelism = maxDegreeOfParallelism ;
2021-04-27 22:41:48 -04:00
2022-03-24 16:35:00 -04:00
ActionBlock < T > actions = new ActionBlock < T > ( action , options ) ;
foreach ( T item in collection )
2021-04-27 22:41:48 -04:00
{
2022-03-24 16:35:00 -04:00
actions . Post ( item ) ;
2021-04-27 22:41:48 -04:00
}
2022-03-24 16:35:00 -04:00
actions . Complete ( ) ;
2021-04-27 22:41:48 -04:00
2022-03-24 16:35:00 -04:00
return actions . Completion ;
2021-04-27 22:41:48 -04:00
}
2020-12-28 14:34:13 -04:00
}
}