Created
June 26, 2021 10:42
-
-
Save fjod/41d4f4ecd8d1355a2e63a9e69366b68a to your computer and use it in GitHub Desktop.
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
using System; | |
using System.Collections.Concurrent; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Net.Http; | |
using System.Threading; | |
using System.Threading.Tasks; | |
using BenchmarkDotNet.Attributes; | |
namespace chapsasParallel | |
{ | |
[SimpleJob(launchCount: 10, warmupCount: 3, targetCount: 20)] | |
[MemoryDiagnoser] | |
public class Test | |
{ | |
private HttpClient _client = new HttpClient(); | |
private int tasksCount = 15; | |
private async Task<string> SampleLoad() | |
{ | |
var ret = await _client.GetStringAsync("http://ya.ru"); | |
Console.Write($"{Thread.CurrentThread.ManagedThreadId} returned {ret.Length} of text"); | |
return ret; | |
} | |
[Benchmark] | |
public async Task<List<string>> A2() => await WhenAll(); | |
[Benchmark] | |
public async Task<List<string>> A3() => await AsyncParallelVersion(tasksCount); | |
public async Task<List<string>> ParallelVersion(int degree) | |
{ | |
var list = new List<string>(); | |
var tasks = Enumerable.Range(0,tasksCount).Select( _ => | |
{ | |
var func = new Func<Task<string>>(async () => await SampleLoad()); | |
return func; | |
}).ToList(); | |
var l1 = tasks[0]; | |
var z = await l1(); | |
//parallel wont work here with async; must use GetAwaiter().GetResult() which I wont do | |
Parallel.For(0, tasks.Count, new ParallelOptions {MaxDegreeOfParallelism = degree}, | |
async i => list.Add(await tasks[i]())); | |
return list; | |
} | |
public async Task<List<string>> WhenAll() | |
{ | |
var list = new List<string>(); | |
var tasks = Enumerable.Range(0,tasksCount).Select(async _ => | |
{ | |
var q = await SampleLoad(); | |
list.Add(q); | |
}).ToList(); | |
await Task.WhenAll(tasks); | |
return list; | |
} | |
public async Task<List<string>> AsyncParallelVersion(int degree) | |
{ | |
var list = new List<string>(); | |
var tasks = Enumerable.Range(0,tasksCount).Select( _ => | |
{ | |
var func = new Func<Task<string>>(async () => await SampleLoad()); | |
return func; | |
}).ToList(); | |
await ParalelForEachAsync(tasks, degree, async f => | |
{ | |
list.Add(await f()); | |
}); | |
return list; | |
} | |
public static Task ParalelForEachAsync<T>(IEnumerable<T> source, int degree, Func<T, Task> body) | |
{ | |
async Task AwaitPartition(IEnumerator<T> partition) | |
{ | |
using (partition) | |
{ | |
while (partition.MoveNext()) | |
{ | |
await body(partition.Current); | |
} | |
} | |
} | |
return Task.WhenAll( | |
Partitioner.Create(source).GetPartitions(degree).AsParallel().Select(AwaitPartition)); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment