Я изучаю async
/ await
и обнаружил любопытный сценарий, для которого мне нужно руководство по разрешению.
Для справки, код, указанный в этом вопросе, можно найти здесь:
https://github.com/Mike-EEE/Stash/tree/master/AwaitPerformance
Я предоставил два простых способа ожидания набора задач.Первый - это просто создание List<Task>
, добавление задач в этот список и ожидание сразу всего результата с вызовом Task.WhenAll
:
public async Task<uint> AwaitList()
{
var list = new List<Task>();
for (var i = 0u; i < 10; i++)
{
list.Add(Task.Delay(1));
}
await Task.WhenAll(list).ConfigureAwait(false);
return 123;
}
Второй - ожидание каждой задачи по мере их возникновенияв цикле for
:
public async Task<uint> AwaitEach()
{
for (var i = 0u; i < 10; i++)
{
await Task.Delay(1).ConfigureAwait(false);
}
return 123;
}
Однако при запуске этих двух методов с Benchmark.NET я получаю удивительно противоречивые результаты:
// * Summary *
BenchmarkDotNet=v0.11.5, OS=Windows 10.0.18362
AMD Ryzen 7 2700X, 1 CPU, 8 logical and 4 physical cores
.NET Core SDK=3.0.100-preview5-011568
[Host] : .NET Core 3.0.0-preview5-27626-15 (CoreCLR 4.6.27622.75, CoreFX 4.700.19.22408), 64bit RyuJIT
DefaultJob : .NET Core 3.0.0-preview5-27626-15 (CoreCLR 4.6.27622.75, CoreFX 4.700.19.22408), 64bit RyuJIT
| Method | Mean | Error | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
|---------- |----------:|----------:|----------:|------:|------:|------:|----------:|
| AwaitList | 15.60 ms | 0.0274 ms | 0.0243 ms | - | - | - | 2416 B |
| AwaitEach | 155.62 ms | 0.9113 ms | 0.8524 ms | - | - | - | 352 B |
Как видите, ожидаяСписок задач намного быстрее, но генерирует массу выделений.Ожидание каждого элемента, однако, является обратным: он медленнее, но генерирует намного меньше мусора.
Есть ли очевидный, идеальный способ, которым я пропускаю, чтобы получить оба лучших мира здесь?То есть есть ли способ ожидания набора из Task
элементов, который является быстрым и приводит к небольшому количеству выделений?
Заранее благодарен за любую помощь.