Created
August 13, 2015 22:11
-
-
Save jhoerr/8daf75c3f517bba2bb52 to your computer and use it in GitHub Desktop.
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 ConcurrentCollectionExtensions | |
{ | |
private const int MaxDegreeOfConcurrency = 10; | |
/// <summary> | |
/// Concurrently perform a task on each member of a collection | |
/// </summary> | |
/// <typeparam name="T"></typeparam> | |
/// <param name="collection">The collection upon which each task should be performed</param> | |
/// <param name="concurrentTask">The task to perform</param> | |
/// <param name="maxDegreeOfConcurrency">The maximum number of concurrent operations</param> | |
/// <returns></returns> | |
public static async Task ConcurrentForEach<T>(this IEnumerable<T> collection, Func<T, Task> concurrentTask, int maxDegreeOfConcurrency = MaxDegreeOfConcurrency) | |
{ | |
var semaphore = new SemaphoreSlim(maxDegreeOfConcurrency); | |
var tasks = collection.Select(async student => | |
{ | |
using (await semaphore.TakeAsync()) | |
await concurrentTask(student); | |
}); | |
await Task.WhenAll(tasks); | |
} | |
} | |
public static class SemaphoreSlimExtensions | |
{ | |
public static async Task<IDisposable> TakeAsync(this SemaphoreSlim semaphore) | |
{ | |
await semaphore.WaitAsync().ConfigureAwait(false); | |
return new SemaphoreSlimKey(semaphore); | |
} | |
private sealed class SemaphoreSlimKey : IDisposable | |
{ | |
private readonly SemaphoreSlim _semaphore; | |
public SemaphoreSlimKey(SemaphoreSlim semaphore) { _semaphore = semaphore; } | |
void IDisposable.Dispose() { _semaphore.Release(); } | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment