C# Polly с пессимистичной стратегией тайм-аута медленно на нескольких потоках?

Рассмотрим этот кусок кода:

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Polly;
using Polly.Timeout;

namespace Test
{
    public class Program
    {
        public static async Task Main()
        {
            var tasks = new List<Task>();

            for (var i = 0; i < 20; i++)
            {
                var task = new Task(Test);
                tasks.Add(task);
            }

            foreach (var task in tasks)
                task.Start();

            await Task.WhenAll(tasks);
        }

        public static void Test()
        {
            Console.WriteLine($"Executing Test() at {DateTime.Now}");

            Policy.Timeout(TimeSpan.FromSeconds(2), TimeoutStrategy.Pessimistic)
                .Execute(() => { Thread.Sleep(200); });
        }
    }
}

Я получаю следующий вывод:

Executing Test() at 2018-05-16 15:10:21
Executing Test() at 2018-05-16 15:10:21
Executing Test() at 2018-05-16 15:10:21
Executing Test() at 2018-05-16 15:10:21
Executing Test() at 2018-05-16 15:10:21
Executing Test() at 2018-05-16 15:10:21
Executing Test() at 2018-05-16 15:10:21
Executing Test() at 2018-05-16 15:10:21
Executing Test() at 2018-05-16 15:10:22
Executing Test() at 2018-05-16 15:10:23
Executing Test() at 2018-05-16 15:10:24
Executing Test() at 2018-05-16 15:10:24
Executing Test() at 2018-05-16 15:10:24
Executing Test() at 2018-05-16 15:10:25
Executing Test() at 2018-05-16 15:10:26
Executing Test() at 2018-05-16 15:10:26
Executing Test() at 2018-05-16 15:10:27
Executing Test() at 2018-05-16 15:10:27
Executing Test() at 2018-05-16 15:10:27
Executing Test() at 2018-05-16 15:10:28

И в самом конце создается исключение Polly.Timeout.TimeoutRejectedException. Я не могу понять, почему это займет так много времени, чтобы выполнить? Исходя из результатов, кажется, что первые 8 задач выполняются параллельно, а затем это становится очень медленным. Без политики тайм-аута или с оптимистичной стратегией тайм-аута она запускается мгновенно. Но в моем случае можно использовать только пессимистичную политику тайм-аута.

Используя последнюю версию Polly, которая является 6.0.1.

1 ответ

Я думаю, что способ добавления задач в список и последующего их запуска не совсем корректен.

Пожалуйста, посмотрите этот ответ ( Относительно использования Task.Start(), Task.Run() и Task.Factory.StartNew ()) для разъяснения о правильном использовании.Start().

Так что в вашем случае все, что вам действительно нужно сделать, это изменить часть добавления на эту

for (var i = 0; i < 20; i++)
{
   tlist.Add(Task.Run(() => Test()));
}

Это решит вашу проблему, и, вероятно, вам не понадобится Полли. Но вы должны быть осторожны с размером вашего списка задач. Вы будете использовать пул потоков.net, чтобы вы не брали физические потоки как есть, но все же это предел того, насколько далеко вы можете продвинуться.

РЕДАКТИРОВАТЬ:

Вам также нужно будет избавиться от этой части здесь

foreach (var task in tasks)
            task.Start();
Другие вопросы по тегам