Эта статья является зеркальной статьёй машинного перевода, пожалуйста, нажмите здесь, чтобы перейти к оригиналу.

Вид: 42759|Ответ: 5

[Источник] Почему задача .net/c# медленнее Thread?

[Скопировать ссылку]
Опубликовано 03.05.2017 16:40:28 | | | |
.NET 4 включает новое пространство имён System.Threading.Tasks, которое содержит классы, абстрагирующие функциональность потоков. Используйте ThreadPool в фоне. Задача представляет собой работу единицы, которую нужно выполнить. Работа этого блока может выполняться в отдельном потоке или выполнять задачу синхронно, что требует ожидания основного потока настройки. Использование задач даёт не только уровень абстракции, но и даёт большой контроль над основными потоками.
Задачи предлагают большую гибкость в планировании необходимых работ. Например, вы можете определить непрерывную задачу — какую работу следует выполнять после завершения задачи. Это может стать решающим фактором между успешной и неуспешной задачей. Кроме того, задачи могут быть организованы по иерархии. Например, родительская задача может создать новую дочернюю задачу. Это создаёт зависимость, так что если вы отмените родительскую задачу, её дочерняя задача тоже будет отменена.


Сегодня популярно использовать методы выполнения задач, и это высокая производительность, и я не знаю, где именно производительность задач.

Я сам тестировал Task and Thread и считаю, что Task работает очень медленно, что сильно влияет на производительность, а тестовый код таков:

Мы повторяем метод 1000 раз, затем метод блокируется на 100 миллисекунд, и результат теста выглядит следующим образом:



Результат:
Выполнение потока занимает 188 миллисекунд
Выполнение задачи занимает 14 671 миллисекунду


Разница в скорости между ними составляет 78 раз!!

Задача очень медленная, не понимаю, почему это происходит, что-то не так с моим тестовым кодом или что-то ещё? Надеюсь, вы сможете объяснить, почему так происходит...




Предыдущий:Отправляйте сообщения с помощью ASP.NET Core
Следующий:C# Параллельные вычисления Parallel.For&Parallel.For
 Хозяин| Опубликовано 13.10.2020 10:47:17 |
tongli1996218 Опубликовано 2020-10-13 09:34
Чтобы обеспечить тот же код, что и Thread, моя операция — следующий код, а вышеуказанный — псевдокод
P.S.: Просто звоните в ожидание задачи. Задержка без добавления...

Да, спасибо

Время выполнения задачи: 117.0357

Вы можете изменить код следующим образом:

Task.Run заменяет Task.Factory.StartNew, потому что автоматически распаковывает внутренние задачи.
Task.WaitAll ждёт внешнюю задачу вместо внутренней. Использование Task.Run не содержит вложенных задач.


Посмотрев документацию msdn, видно, что метод Task.Delay Method создаёт задачу, которая завершается через определённое количество миллисекунд. (На самом деле, будет создан новый поток, который будет добавлен, чтобы ждать выполнения задачи, не уверен, правильно ли я понял)

Вход по гиперссылке виден.

Кроме того, существует разница между задачей и пустотой

Задача возвращает асинхронный метод, который может подождать
Асинхронный метод void return не может ждать, он работает асинхронно, нельзя знать, когда всё закончено, нельзя отслеживать статус этой асинхронной операции.


Ссылка:

Вход по гиперссылке виден.
Вход по гиперссылке виден.

В итоге: с кодом возникла проблема, не стоит использовать Thread.Sleep внутри метода задачи
Опубликовано 21.07.2020 13:09:29 |
У меня сегодня была такая же проблема: я использую многопоточность для шифрования AES, Task работает гораздо медленнее Thread!!
Арендодатель нашёл причину?
Опубликовано 12.10.2020 19:24:48 |
Этот пост был последний раз отредактирован tongli1996218 12.10.2020 19:43

После тестирования кода владельца, когда программа запускается и запускается несколько раз, время выполнения задачи продолжает уменьшаться, и на моём компьютере оно сокращается до меньшего уровня потока, при этом поток стабилен в это время.

Позже было установлено, что метод Thread.Sleep(100) негативно влияет на Task, но не на Thread, и Thread.Sleep(100) можно заменить другими трудоёмкими программами проверки, такими как числовое самосложение или ожидание Task.Delay(100).

P.S.: Thread.Sleep завершает текущее время слайзинга потока после вызова, например, Thread.Sleep(0) завершает текущее время слайзинга потока и передаёт его другим потокам для запуска. Внутри задачи находится пул потоков, который может оптимизировать переключение контекста потоков и сократить время потерь процессора (особенно при многоядерной оптимизации процессора), в то время как Thread.Sleep(100) нарушает логику переключения исходного пула потоков задачи, вызывая значительные потери времени процессора

Если заменить Thread.Sleep(100) на wait.Task.Delay(100), вы обнаружите, что время выполнения задачи превышает 100 миллисекунд, как показано ниже:
private void TaskTest()
{
        Thread.Sleep (100);
         ... Выполните действие
}
Заменён
private async void TaskTest()
{
      ждать задание. Задержка (100);
      ... Выполнение задачи занимает более 100 миллисекунд, что соответствует оригинальному Thread.Sleep(100) для Thread
}




 Хозяин| Опубликовано 12.10.2020 22:53:05 |
tongli1996218 Опубликовано 2020-10-12 19:24
После тестирования кода владельца, когда программа запускается, время выполнения задачи будет продолжать уменьшаться после многократных запусков, а на моём компьютере оно сокращается до меньшего уровня Thread...

Я попробовал изменить его на код вот так:
Задача.Задержка(100000);

Время выполнения задачи:14,1306 мс, общее время действительно очень мало, однако я обнаружил, что метод, вызванный Задачей, не завершил выполнение.
Опубликовано 13.10.2020 9:34:33 |
Этот пост был последний раз отредактирован tongli1996218 13.10.2020 09:40
Опубликовано 2020-10-12 22:53
Я попробовал изменить его на код вот так:
Задача.Задержка (100000);

Чтобы обеспечить тот же код, что и Thread, моя операция — следующий код, а вышеуказанный — псевдокод
P.S.: Просто вызовите Wait.Task.Delay и не добавляйте код, поток, открытый задачей, возвращается немедленно, чтобы обеспечить симуляцию вычислительной задержки, которую можно использовать для (int a = 0; a< 1000000; ++a){}; Вместо этого такие методы

private async static void TaskTest()
        {
            ждать задачу. Задержка (100000);
             Interlocked.Increment (проверка по ссылкам);    Lock, но верхние расходы меньше
            if(run == j)
             {
                секундомер. Стоп(); Прекратить мониторинг
                TimeSpan timespan = секундомер. Прошло;  Получает общее время, измеряемое текущим экземпляром
                Console.WriteLine("Время выполнения задачи:" + временной интервал. TotalMilliseconds); Общее количество миллисекунд
              }
        Время, потраченное на неё, тоже очень мало


Отказ:
Всё программное обеспечение, программные материалы или статьи, публикуемые Code Farmer Network, предназначены исключительно для учебных и исследовательских целей; Вышеуказанный контент не должен использоваться в коммерческих или незаконных целях, иначе пользователи несут все последствия. Информация на этом сайте взята из Интернета, и споры по авторским правам не имеют отношения к этому сайту. Вы должны полностью удалить вышеуказанный контент с компьютера в течение 24 часов после загрузки. Если вам нравится программа, пожалуйста, поддержите подлинное программное обеспечение, купите регистрацию и получите лучшие подлинные услуги. Если есть нарушение, пожалуйста, свяжитесь с нами по электронной почте.

Mail To:help@itsvse.com