Подтвердить что ты не робот

Thread.Start() против ThreadPool.QueueUserWorkItem()

Библиотека базового класса Microsoft.NET предоставляет несколько способов создания потока и запуска его. В принципе, вызов очень похож на любой другой, предоставляющий один и тот же сервис: создайте объект, представляющий поток выполнения (или более), назначьте ему делегат, представляющий исполняемый поток для выполнения, и, в конечном счете, в зависимости от подписи делегата, объекта как параметр.

Ну, есть два подхода (по существу):

1) Использование класса System.Threading.Thread.

Thread curr = new Thread(myfunction); /* In a class, myfunction is a void taking an object */
curr.Start(new Object()); /* Or something else to be downcast */

2) Используя класс System.Threading.ThreadPool.

ThreadPool.QueueUserWorkItem(myfunction, new Object()); /* Same philosophy here */

Существуют ли какие-либо особые причины, по которым я должен использовать 1) или 2)? Почему? Узоры? Каков наилучший подход?

У меня такое чувство, что ответ: "Зависит от ситуации". Не могли бы вы перечислить некоторые ситуации, когда один подход лучше другого?

4b9b3361

Ответ 1

Запуск нового потока может быть очень дорогостоящей операцией. Пул потоков повторно использует потоки и, таким образом, амортизирует стоимость. Если вам не нужен выделенный поток, рекомендуется использовать пул потоков. Используя выделенный поток, вы имеете больше контроля над атрибутами, специфичными для потока, такими как приоритет, культура и т.д. Кроме того, вы не должны выполнять длительные задачи в пуле потоков, поскольку это заставляет пул создавать дополнительные потоки.

В дополнение к вариантам, которые вы упомянули,.NET 4 предлагает отличные абстракции для concurrency. Проверьте классы Task и Parallel, а также все новые методы PLINQ.

Ответ 2

В пуле управляемых потоков есть некоторые очень хорошие рекомендации, когда НЕ использовать пул потоков.

По моему опыту, вы хотите создать свой собственный поток, если вам нужен постоянный выделенный выделенный длинный поток. Для всего остального используйте асинхронные делегаты или что-то вроде QueueUserWorkItem, BackgroundWorker или связанные с Task функции .NET 4.0.

Ответ 3

Темы ThreadPool являются фоновыми потоками; Все потоки, созданные и запущенные новым объектом Thread, являются потоками переднего плана.

Фоновый поток не поддерживает запущенную среду управления.

обратитесь к http://msdn.microsoft.com/en-us/library/h339syd0.aspx для более подробной информации.

Ответ 4

В .NET 4.5.2 они добавили новый метод: HostingEnvironment.QueueBackgroundWorkItem.

Это выглядит как альтернатива ThreadPool.QueueUserWorkItem. Оба ведут себя аналогичным образом, но есть некоторые хорошие преимущества для использования нового метода при работе в ASP.NET:

Метод HostingEnvironment.QueueBackgroundWorkItem позволяет вам график небольших работ фона. ASP.NET отслеживает эти элементы и не позволяет IIS резко прекратить рабочий процесс до тех пор, пока все фоновые рабочие элементы завершены. Этот метод нельзя назвать вне домена управляемого приложения ASP.NET.

Ответ 5

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

Ответ 6

ThreadPool.QueueUserWorkItem() в основном относится к сценариям "огонь и забухание", когда приложение не зависит от завершения операций или нет.

Используйте классические потоки для мелкозернистого управления.