Если я создаю новый поток на странице ASP.NET, свойство IsThreadPoolThread
истинно. Первый вопрос: это из пула ASP.NET или пула CLR? Второй вопрос: если он из пула ASP.NET, то как создать поток из CLR и не использовать пул ASP.NET? Мне нужно синхронное решение для длительных запросов (полная история).
Как создавать потоки на страницах ASP.NET из пула потоков CLR вместо пула ASP.NET?
Ответы (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
Хотя есть необходимость минимизировать влияние на транзакции и учесть непредвиденные обстоятельства в распределенных транзакциях, в этом примере действительно нет необходимости заново изобретать IIS только потому, что процесс выполняется долго. Весь мем "ИИС может умереть в любой момент" ИМХО сильно преувеличен.
Да, вы можете вручную перезапустить IIS или пул приложений, но также можете перезапустить любую другую службу, которая выполняет ту же работу с тем же эффектом. Что касается автоматической перезагрузки, IIS использует перекрывающиеся рабочие процессы и никогда не завершит запущенный поток принудительно (если не истечет время ожидания). Если бы это было так, у нас были бы серьезные проблемы с любым размещенным приложением (что помешает IIS убить поток быстрого ответа через 0,001 мс после запуска)
По сути, позвольте IIS делать то, что IIS делает лучше всего, и не настаивать на операции синхронизации, вы просто тратите поток пула в ожидании блокировки ввода-вывода, чего, я полагаю, вы пытаетесь избежать. Вы уже сделали хороший выбор, перейдя к Асинхронным обработчикам (ASHX), используйте IHttpAsyncHandler
реализацию для создания вашего настраиваемого потока, который затем будет блокироваться по вашему желанию, не затрагивая веб-приложение и его пул. Как только вы инициируете поток асинхронной операции, поток asp.net вернется в свой собственный пул и будет готов начать обслуживание нового запроса. С ограничением по умолчанию в 100 потоков в пуле и с учетом того, что ваш процесс имеет мало ресурсов процессора и высокую пропускную способность, я сомневаюсь, что у вас когда-нибудь закончатся потоки пула, прежде чем у вас закончится пространство канала :). Для получения дополнительной информации о том, как создать асинхронный обработчик, проверьте эту ссылку (это старая статья, но, тем не менее, действительная):
Используйте потоки и создавайте асинхронные обработчики в своем серверном веб-коде
На самом деле существует разница в потоках в ASP .NET: рабочие потоки и потоки ввода-вывода (системные потоки, которые, как я полагаю, вы указываете как поток CLR).
Теперь ASP .NET использует рабочий поток для каждого запроса, если не используются пользовательские конфигурации, и эти рабочие потоки ограничены вашим числом ЦП; эту конфигурацию можно настроить в IIS. Когда вы запускаете асинхронную задачу внутри ASP.NET с помощью, например, делегата, вы используете другой рабочий поток. Делегаты - это быстрый и грязный способ запустить что-то асинхронное в .NET :)
Если вы хотите запустить новый поток, который НЕ использует рабочий поток, вы должны явно запустить новый поток, например: new Thread () .... и т. Д. Теперь это идет с большим количеством управления кодом и не следует асинхронному шаблону, основанному на событиях. Однако есть один способ безопасно запускать асинхронные потоки - использовать собственные асинхронные методы .NET для объектов. Вещи, которые вы обычно использовали бы асинхронно, например, для команд SQL, вызовов веб-сервисов и т. Д. Все они имеют методы BEGIN и END. Используя эти методы, вы никогда не будете использовать рабочий поток, а будете использовать поток ввода-вывода.
У ASP .NET есть несколько хитростей, когда дело касается асинхронных страниц. Есть две альтернативы:
- Асинхронная страница: позволяет циклу вашей страницы быть асинхронным. В основном это означает, что страница запрашивается асинхронно.
- Асинхронные задачи страницы: позволяет определять задачи, которые будут запускаться асинхронно при запуске страницы. Это вроде как потоки Asynch, просто ASP .NET многое делает за вас, и это более ограниченно.
У меня нет всех подробностей, но, пожалуйста, ознакомьтесь с двумя вариантами в библиотеке MSDN. Вот статья на эту тему: асинхронная программа