C # создает несколько задач, выполнение одной задачи медленнее, чем не параллельное - PullRequest
0 голосов
/ 24 сентября 2019

у меня есть эта часть кода

bool hasData = true;
using (Context context = new Context())
{
    using (SemaphoreSlim concurrencySemaphore = new SemaphoreSlim(MAX_THREADS))
    {
        while (hasData)
        {
            Message message = context.Database.SqlQuery<Message>($@"
select top(1) * from Message  where 
( Status = {(int)MessageStatusEnum.Pending} ) or 
( Status = {(int)MessageStatusEnum.Paused } and ResumeOn < GETUTCDATE() )
            ").FirstOrDefault();

            if message == null)
            {
                hasData = false;
            }
            else
            {

                concurrencySemaphore.Wait();

                tasks.Add(Task.Factory.StartNew(() =>
                {
                    Process(message);

                    concurrencySemaphore.Release();

                }, this.CancellationToken));

            }
        }
        Task.WaitAll(tasks.ToArray());
    }
}

И моя функция Process выглядит примерно так

private void Process(Message message)
{
    System.Threading.Thread.Sleep(10000);
}

Теперь, если у меня есть только 1 элемент, который я хочу обработать, тогдаобщее время выполнения составляет 10 с, а время выполнения на элемент (1 элемент) составляет 10 с.Например, если у меня есть 10 элементов, выполнение каждого элемента увеличивается до 15-20 секунд.

Я пытался изменить значение MAX_THREADS, но всегда, если в моей очереди более 10 элементов, и запускаюпараллельное выполнение, тогда время выполнения на элемент составляет около 15 секунд.

Чего мне не хватает?

1 Ответ

0 голосов
/ 24 сентября 2019

Не неожиданно. Параллельное замедление - это очень реальная проблема.На одном конце у нас есть приятно параллельные операции.С другой стороны, по сути, последовательные вещи, такие как вычисление последовательности Фибоначчи.И между ними много областей.

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

  • более сложный
  • больше памяти, требующей
  • инаиболее важно медленнее , чем простая последовательная операция

В лучшем случае вы просто добавили все эти накладные расходы управления задачами в операцию.В худшем случае вы сталкиваетесь с тупиками и конкуренцией за ресурсы.И ваша примерная операция «Спящий поток» - это не то, что в любом случае принесет пользу многозадачности.Пожалуйста, покажите нам актуальную операцию, которую вы хотите ускорить с помощью многозадачности.Поэтому мы можем сказать вам, есть ли шанс, что это сработает.

...