. net - Производительность в случае асинхронности / ожидания внутри выбора - PullRequest
2 голосов
/ 29 апреля 2020

Интересно, почему в конкретном случае c существует некое «ограничение» в параллельном процессе, касающемся асинхронности / ожидания. Например, этот фрагмент кода (работает на. net core 3.1):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

public class Program
{
        async static Task Main(string[] args)
        {
            Console.WriteLine("Before - " + DateTime.Now.ToLongTimeString());
            var list = await (Task.WhenAll((await GetList()).Select(async l => new { Value = l, Text = await Wait(l) })));
            Console.WriteLine("After - " + DateTime.Now.ToLongTimeString());
            Console.WriteLine("Count - " + list.Count());

            Console.ReadLine();
        }

        async static Task<IEnumerable<int>> GetList()
        {
            IEnumerable<int> list = Enumerable.Range(1, 20);
            return await Task.FromResult(list);
        }

        async static Task<string> Wait(int index)
        {
            Console.WriteLine(index + " - During Before - " + DateTime.Now.ToLongTimeString());
            await Task.Run(() => {
                Thread.Sleep(5000);
            });
            Console.WriteLine(index + " - During After - " + DateTime.Now.ToLongTimeString());

            return "ok";
        }
}

Итак, я ожидаю получить свои 20 элементов обработки массива одновременно, а через 5 секунд освободить все из них и fini sh программа.

Вот вывод:

Before - 12:11:05
1 - During Before - 12:11:05
2 - During Before - 12:11:05
3 - During Before - 12:11:05
4 - During Before - 12:11:05
5 - During Before - 12:11:05
6 - During Before - 12:11:05
7 - During Before - 12:11:05 
8 - During Before - 12:11:05 
9 - During Before - 12:11:05 
10 - During Before - 12:11:05
11 - During Before - 12:11:05
12 - During Before - 12:11:05
13 - During Before - 12:11:05
14 - During Before - 12:11:05
15 - During Before - 12:11:05
16 - During Before - 12:11:05
17 - During Before - 12:11:05
18 - During Before - 12:11:05
19 - During Before - 12:11:05
20 - During Before - 12:11:05
1 - During After - 12:11:10
2 - During After - 12:11:10
4 - During After - 12:11:10
3 - During After - 12:11:10
7 - During After - 12:11:10
8 - During After - 12:11:10
6 - During After - 12:11:10
5 - During After - 12:11:10
9 - During After - 12:11:11
10 - During After - 12:11:12
11 - During After - 12:11:13
12 - During After - 12:11:14
13 - During After - 12:11:15
14 - During After - 12:11:15
15 - During After - 12:11:15
16 - During After - 12:11:15
18 - During After - 12:11:15
17 - During After - 12:11:15
19 - During After - 12:11:15
20 - During After - 12:11:15
After - 12:11:15
Count - 20

Потребовалось 10 секунд для запуска вместо 5 с.

Все нормально для 20 «Во время до». Как и ожидалось.
Но в течение следующих 20 "Во время после", с 9 до 13, каждый поток завершается каждую секунду.
Так что я предполагаю, что во время этого фрагмента кода есть что-то определенное c, но я не не понимаю, что:

(await GetList()).Select(async l => new { Value = l, Text = await Wait(l) })

У кого-нибудь есть объяснения, пожалуйста?

1 Ответ

0 голосов
/ 29 апреля 2020

ThreadPool - это обходной путь проблемы, и он может запускать процесс с меньшими ограничениями. Но дело все еще в этом.
Но, зная это, вы получите ответ на проблему:

В коде root проблемы равен Task.Run, как и использование TreadPool для обработки делегата. .
Так что напрямую используйте внутренний метод или замените Task.Run чем-то другим, чтобы решить исходную проблему.

...