Как создавать потоки на страницах ASP.NET из пула потоков CLR вместо пула ASP.NET?

Если я создаю новый поток на странице ASP.NET, свойство IsThreadPoolThread истинно. Первый вопрос: это из пула ASP.NET или пула CLR? Второй вопрос: если он из пула ASP.NET, то как создать поток из CLR и не использовать пул ASP.NET? Мне нужно синхронное решение для длительных запросов (полная история).


person Xaqron    schedule 24.10.2010    source источник


Ответы (3)


Во-первых, нет никакой разницы между пулом потоков ASP.NET и пулом потоков CLR. ASP.NET обрабатывает страницы в пуле потоков CLR, поэтому ваши страницы ASP.NET всегда будут иметь IsThreadPoolThread == true.

Мне любопытно, как вы создаете свою ветку. Вы используете конструктор System.Threading.Thread или ThreadPool.QueueUserWorkItem? Если вы используете ThreadPool.QueueUserWorkItem, то потоки, которые вы получаете, поступают из обычного пула потоков .net.

Наконец, поскольку я опубликовал ранее, это всегда плохая идея для попытки выполнения длительных задач из ASP.NET. Мое общее предложение - использовать фоновую службу Windows для обработки этих запросов, поскольку ASP.NET может прервать ваш фоновый поток в любой момент. Подробнее здесь, если вам необходимо сделать это в IIS: http://csharpfeeds.com/post/5415/Dont_use_the_ThreadPool_in_ASP.NET.aspx

person Chris Shain    schedule 06.02.2011
comment
Конечно, создание нового потока вручную из asp.net не приведет к тому, что IsThreadPoolThread будет установлено в значение true, верно? Значит, он должен вызывать QueueUserWorkItem. Пожалуйста, поправьте меня, если я ошибаюсь. - person Fantius; 08.02.2011
comment
Правильно, я просто отстаивал свое здравомыслие. - person Chris Shain; 08.02.2011
comment
Для этих потоков IsThreadPoolThread должно быть ложным. Вы уверены, что это правда? - person Chris Shain; 08.02.2011

Хотя есть необходимость минимизировать влияние на транзакции и учесть непредвиденные обстоятельства в распределенных транзакциях, в этом примере действительно нет необходимости заново изобретать IIS только потому, что процесс выполняется долго. Весь мем "ИИС может умереть в любой момент" ИМХО сильно преувеличен.

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

По сути, позвольте IIS делать то, что IIS делает лучше всего, и не настаивать на операции синхронизации, вы просто тратите поток пула в ожидании блокировки ввода-вывода, чего, я полагаю, вы пытаетесь избежать. Вы уже сделали хороший выбор, перейдя к Асинхронным обработчикам (ASHX), используйте IHttpAsyncHandler реализацию для создания вашего настраиваемого потока, который затем будет блокироваться по вашему желанию, не затрагивая веб-приложение и его пул. Как только вы инициируете поток асинхронной операции, поток asp.net вернется в свой собственный пул и будет готов начать обслуживание нового запроса. С ограничением по умолчанию в 100 потоков в пуле и с учетом того, что ваш процесс имеет мало ресурсов процессора и высокую пропускную способность, я сомневаюсь, что у вас когда-нибудь закончатся потоки пула, прежде чем у вас закончится пространство канала :). Для получения дополнительной информации о том, как создать асинхронный обработчик, проверьте эту ссылку (это старая статья, но, тем не менее, действительная):

Используйте потоки и создавайте асинхронные обработчики в своем серверном веб-коде

person mmix    schedule 08.02.2011

На самом деле существует разница в потоках в ASP .NET: рабочие потоки и потоки ввода-вывода (системные потоки, которые, как я полагаю, вы указываете как поток CLR).

Теперь ASP .NET использует рабочий поток для каждого запроса, если не используются пользовательские конфигурации, и эти рабочие потоки ограничены вашим числом ЦП; эту конфигурацию можно настроить в IIS. Когда вы запускаете асинхронную задачу внутри ASP.NET с помощью, например, делегата, вы используете другой рабочий поток. Делегаты - это быстрый и грязный способ запустить что-то асинхронное в .NET :)

Если вы хотите запустить новый поток, который НЕ использует рабочий поток, вы должны явно запустить новый поток, например: new Thread () .... и т. Д. Теперь это идет с большим количеством управления кодом и не следует асинхронному шаблону, основанному на событиях. Однако есть один способ безопасно запускать асинхронные потоки - использовать собственные асинхронные методы .NET для объектов. Вещи, которые вы обычно использовали бы асинхронно, например, для команд SQL, вызовов веб-сервисов и т. Д. Все они имеют методы BEGIN и END. Используя эти методы, вы никогда не будете использовать рабочий поток, а будете использовать поток ввода-вывода.

У ASP .NET есть несколько хитростей, когда дело касается асинхронных страниц. Есть две альтернативы:

  1. Асинхронная страница: позволяет циклу вашей страницы быть асинхронным. В основном это означает, что страница запрашивается асинхронно.
  2. Асинхронные задачи страницы: позволяет определять задачи, которые будут запускаться асинхронно при запуске страницы. Это вроде как потоки Asynch, просто ASP .NET многое делает за вас, и это более ограниченно.

У меня нет всех подробностей, но, пожалуйста, ознакомьтесь с двумя вариантами в библиотеке MSDN. Вот статья на эту тему: асинхронная программа

person Deleo    schedule 09.02.2011