Использование ThreadPool. QueueUserWorkItem в ASP.NET в сценарии интенсивного трафика

Этим вопросом была активная область исследования в прошлых годах. Основная идея состоит в том, чтобы сделать , предварительная обработка на графике однажды , к [1 111] убыстряются весь после запросов . С этой дополнительной информацией маршруты могут быть вычислены очень быстро. Однако, Алгоритм Dijkstra является основанием для всех оптимизаций.

Паукообразное насекомое описало использование двунаправленного поиска и граничного сокращения на основе иерархической информации. Эти методы ускорения работают вполне хорошо, но новые алгоритмы превосходят эти методы по характеристикам любой ценой. С текущими алгоритмами кратчайшие пути могут быть вычислены в значительном меньше времени, чем [1 114] одна миллисекунда на континентальной дорожной сети. Внедрение FAST неизмененного алгоритма потребностей Dijkstra приблизительно [1 115] 10 секунд .

Разработка статьи Быстрые Алгоритмы Планирования Маршрута дает обзор прогресса исследования в том поле. Посмотрите ссылки той бумаги для получения дополнительной информации.

самые быстрые известные алгоритмы не используют информацию об иерархическом состоянии дороги в данных, т.е. если это - магистраль или локальная дорога. Вместо этого они вычисляют на шаге предварительной обработки собственную иерархию, которая оптимизировала для ускорения планирования маршрута. Это предварительное вычисление может затем использоваться для сокращения поиска: Далеко от запуска и целевых медленных дорог не должен быть рассмотрен во время Алгоритма Dijkstra. Преимущества очень хороши производительность и правильность гарантия результата.

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

при необходимости в расстояниях кратчайшего пути для вычислений решения для TSP, затем Вы, вероятно, интересуетесь матрицами, которые содержат все расстояния между Вашими источниками и местами назначения. Для этого Вы могли рассмотреть Вычисления Кратчайшие пути Many-Many Используя Магистральные Иерархии . Обратите внимание на то, что это было улучшено более новыми подходами за прошлые 2 года.

109
задан deostroll 3 October 2011 в 03:47
поделиться

9 ответов

Другие ответы здесь, похоже, уходят Из наиболее важного момента:

Если вы не пытаетесь распараллелить операцию, интенсивно использующую ЦП, чтобы ускорить ее выполнение на сайте с низкой нагрузкой, нет никакого смысла использовать рабочий поток вообще.

Это касается как бесплатных потоков, созданных new Thread (...) , так и рабочих потоков в ThreadPool , которые отвечают на запросы QueueUserWorkItem .

Да, это правда, вы можете истощить ThreadPool в процессе ASP.NET, поставив в очередь слишком много рабочих элементов. Это предотвратит обработку дальнейших запросов ASP.NET.Информация в статье является точной в этом отношении; тот же пул потоков, который используется для QueueUserWorkItem , также используется для обслуживания запросов.

Но если вы действительно ставите в очередь достаточно рабочих элементов, чтобы вызвать это голодание, тогда вы должны истощить пул потоков! Если вы выполняете буквально сотни операций с интенсивным использованием ЦП одновременно, что хорошего в том, чтобы иметь другой рабочий поток для обслуживания запроса ASP.NET, когда машина уже перегружена? Если вы столкнулись с такой ситуацией, вам нужно полностью переделать дизайн!

В большинстве случаев я вижу или слышу о том, что многопоточный код используется ненадлежащим образом в ASP.NET, это не для постановки в очередь работы, интенсивно использующей процессор. Это для постановки в очередь работы, связанной с вводом-выводом. И , если вы хотите выполнять операции ввода-вывода, вам следует использовать поток ввода-вывода (порт завершения ввода-вывода).

В частности, вы должны использовать асинхронные обратные вызовы, поддерживаемые любым библиотечным классом, который вы используете. Эти методы всегда очень четко обозначены; они начинаются со слов Begin и End . Аналогично Stream.BeginRead , Socket.BeginConnect , WebRequest.BeginGetResponse и так далее.

Эти методы действительно используют ThreadPool , но они используют IOCP, которые не мешают запросам ASP.NET. Это особый вид облегченного потока, который может быть «разбужен» сигналом прерывания от системы ввода-вывода. И в ASP.NET, у вас обычно есть один поток ввода-вывода для каждого рабочего потока, поэтому для каждого отдельного запроса может быть поставлена ​​в очередь одна асинхронная операция. Это буквально сотни асинхронных операций без какого-либо значительного снижения производительности (при условии, что подсистема ввода-вывода может не отставать). Это намного больше, чем вам когда-либо понадобится.

Просто имейте в виду, что делегаты async не работают таким образом - они будут использовать рабочий поток, как и ThreadPool.QueueUserWorkItem . Это могут делать только встроенные асинхронные методы классов библиотеки .NET Framework. Вы можете сделать это сами, но это сложно и немного опасно и, вероятно, выходит за рамки этого обсуждения.

На мой взгляд, лучший ответ на этот вопрос - не использовать ThreadPool или фоновый экземпляр Thread в ASP.NET ]. Это совсем не похоже на запуск потока в приложении Windows Forms, где вы делаете это, чтобы пользовательский интерфейс оставался отзывчивым и не заботился о том, насколько он эффективен. В ASP.NET вас беспокоит пропускная способность , и все эти переключения контекста на всех этих рабочих потоках абсолютно убивают вашу пропускную способность, независимо от того, используете ли вы ThreadPool или не.

Пожалуйста, если вы обнаружите, что пишете код потоковой передачи в ASP.NET - подумайте, можно ли его переписать для использования уже существующих асинхронных методов, а если нет, то подумайте, действительно ли вы нужен код для запуска в фоновом потоке вообще.В большинстве случаев вы, вероятно, будете добавлять сложность без чистой выгоды.

103
ответ дан 24 November 2019 в 03:24
поделиться

Веб-сайты не должны порождать потоки .

Обычно вы переносите эту функцию в службу Windows, с которой вы затем общаетесь (я использую MSMQ, чтобы поговорить с ними). ​​

- Edit

Я описал реализацию здесь: На основе очередей Фоновая обработка в веб-приложении ASP.NET MVC

- Правка

Чтобы объяснить, почему это даже лучше, чем просто потоки:

Используя MSMQ, вы можете связываться с другим сервером. Вы можете писать в очередь между машинами, поэтому, если вы по какой-то причине определите, что ваша фоновая задача слишком сильно использует ресурсы главного сервера, вы можете просто перенести ее довольно тривиально.

4
ответ дан 24 November 2019 в 03:24
поделиться

Я определенно думаю, что общей практикой для быстрой асинхронной работы с низким приоритетом в ASP.NET было бы использование пула потоков .NET, особенно для сценариев с высоким трафиком, если вы хотите, чтобы ваши ресурсы быть ограниченным.

Кроме того, реализация потоковой передачи скрыта - если вы начинаете создавать свои собственные потоки, вы также должны правильно управлять ими. Я не говорю, что вы не можете этого сделать, но зачем изобретать это колесо?

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

Если у вас нет проблем с производительностью, выберите создание новых потоков, чтобы уменьшить конкуренцию с ASP. Очередь запросов .NET - это классическая преждевременная оптимизация.

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

4
ответ дан 24 November 2019 в 03:24
поделиться

Эта статья неверна. ASP.NET имеет собственный пул потоков, управляемые рабочие потоки для обслуживания запросов ASP.NET. Этот пул обычно состоит из нескольких сотен потоков и отделен от пула ThreadPool, который несколько меньше числа процессоров.

Использование ThreadPool в ASP.NET не будет мешать рабочим потокам ASP.NET. Можно использовать ThreadPool.

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

Использование нового потока для каждого сообщения определенно излишне.

Другой вариант, если вы только говорите насчет ведения журнала - использовать такую ​​библиотеку, как log4net.

1
ответ дан 24 November 2019 в 03:24
поделиться

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

Существует один пул потоков на процесс. Пул потоков имеет размер по умолчанию 250 рабочих потоков на доступное процессор и 1000 операций ввода-вывода потоки. Количество потоков в пул потоков можно изменить с помощью метод SetMaxThreads. Каждый поток использует размер стека по умолчанию и запускает с приоритетом по умолчанию.

1
ответ дан 24 November 2019 в 03:24
поделиться

I was asked a similar question at work last week and I'll give you the same answer. Why are you multi threading web applications per request? A web server is a fantastic system optimized heavily to provide many requests in a timely fashion (i.e. multi threading). Think of what happens when you request almost any page on the web.

  1. A request is made for some page
  2. Html is served back
  3. The Html tells the client to make further requets (js, css, images, etc..)
  4. Further information is served back

You give the example of remote logging, but that should be a concern of your logger. An asynchronous process should be in place to receive messages in a timely fashion. Sam even points out that your logger (log4net) should already support this.

Sam is also correct in that using the Thread Pool on the CLR will not cause issues with the thread pool in IIS. The thing to be concerned with here though, is that you are not spawning threads from a process, you are spawning new threads off of IIS threadpool threads. There is a difference and the distinction is important.

Threads vs Process

Both threads and processes are methods распараллеливания приложения. Однако процессы независимы исполнительные единицы, которые содержат свои собственные сообщать информацию, использовать свои адресных пространств и взаимодействовать только с друг друга через межпроцесс механизмы коммуникации (обычно управляется операционной системой). Приложения обычно делятся в процессы во время проектирования фаза и главный процесс явно порождает подпроцессы, когда делает смысл логически отделить значительная функциональность приложения. Другими словами, процессы - это архитектурная конструкция.

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

Источник

1
ответ дан 24 November 2019 в 03:24
поделиться

Просто используйте класс StreamWriter и Закройте файл соответствующим образом. Маркер EOF будет обработан правильно.

-121--3808409-

Отсутствует открытый API, позволяющий изменить аудиоустройство по умолчанию, т.е. функциональность, которая считается находящейся под управлением пользователей. Так всегда было в Windows.

Сказав, что, если вы ищете в Интернете, есть несколько людей, которые провели обратную разработку API, которые используются в Windows Vista для этого, но я не собираюсь указывать на них (обратная разработка API являются внутренними неподдерживаемыми API и могут измениться без уведомления от Microsoft). Вы используете эти решения на свой страх и риск.

-121--3502539-

Я не согласен с указанным товаром (C # feeds.com). Создать новую нить несложно, но опасно. Оптимальное количество активных потоков для работы на одном ядре на самом деле удивительно мало - менее 10. Путь слишком легко заставить машину тратить время на переключение потоков, если потоки создаются для незначительных задач. Потоки - это ресурс, который ТРЕБУЕТ управления. Абстракция WorkItem предназначена для обработки.

Здесь существует компромисс между уменьшением количества потоков, доступных для запросов, и созданием слишком большого количества потоков, чтобы обеспечить эффективную обработку любого из них. Это очень динамичная ситуация, но я думаю, что она должна активно управляться (в данном случае пулом потоков), а не оставлять ее процессору, чтобы оставаться впереди создания потоков.

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

0
ответ дан 24 November 2019 в 03:24
поделиться

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

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

0
ответ дан 24 November 2019 в 03:24
поделиться

Вам следует использовать QueueUserWorkItem и избегать создания новых потоков, как если бы вы избежали чумы.Для наглядного изображения, объясняющего, почему вы не будете морить ASP.NET голодом, поскольку он использует тот же ThreadPool, представьте себе очень опытного жонглера, который двумя руками держит в полете полдюжины кеглей для боулинга, мечей или чего-то еще. Чтобы наглядно понять, почему создавать собственные потоки - это плохо, представьте, что происходит в Сиэтле в час пик, когда интенсивно используемые въездные пандусы на шоссе позволяют транспортным средствам немедленно въезжать в движение, вместо того, чтобы использовать свет и ограничивать количество въездов до одного каждые несколько секунд. . Наконец, подробное объяснение см. По этой ссылке:

http://blogs.msdn.com/tmarq/archive/2010/04/14/performing-asynchronous-work-or-tasks-in-asp-net -applications.aspx

Спасибо, Томас

2
ответ дан 24 November 2019 в 03:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: