Last active
December 14, 2019 17:00
-
-
Save hallojoe/fb9b2b7fb471da43927452c0ecdacf41 to your computer and use it in GitHub Desktop.
Executes a collection of functions, in parallel managed by a semaphore.
This file contains hidden or 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
/// <summary> | |
/// Executes a list of functions, in parallel managed by a semaphore. | |
/// </summary> | |
/// <typeparam name="T"></typeparam> | |
/// <param name="values">The values to act on.</param> | |
/// <param name="maxDegreeOfParallelism">Maximum degree of parallelism when executing functions.</param> | |
/// <param name="fn">Function to call using value.</param> | |
/// <returns></returns> | |
public static async Task ManagedForEachAsync<T>(this IEnumerable<T> values, int maxDegreeOfParallelism, Func<T, Task> fn) | |
{ | |
// initialize manager(semaphore) | |
var resourceManager = new SemaphoreSlim(maxDegreeOfParallelism, maxDegreeOfParallelism); | |
// list of tasks to throttle | |
var throttledTasks = new List<Task>(); | |
// iterate values | |
foreach (var value in values) | |
{ | |
// await resource available signal | |
await resourceManager.WaitAsync(); | |
// add task to run | |
throttledTasks.Add(Task.Run(async () => | |
{ | |
// await finish task function | |
await fn(value).ContinueWith(res => | |
{ | |
// release resource | |
resourceManager.Release(); | |
}); | |
})); | |
} | |
// Wait for all tasks to complete. | |
await Task.WhenAll(throttledTasks.ToArray()).ContinueWith(x => | |
{ | |
// dispose resourceManager | |
resourceManager.Dispose(); | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment