Поместите несколько HTTP-запросов для ожидания одного и того же порта завершения ввода-вывода

Мое приложение загружает асинхронно большой объем информации из веб-службы и «Application_Start».

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

Проблема в том, что Monitor.Wait заблокирует поток CLR ThreadPool, и, насколько мне известно, если приходит пачка запросов с просьбой предоставить «большую информацию», приложение может оставаться заблокированным из-за голодания CLR ThreadPool (у меня есть небольшой беспорядок с текущим стробированием потоков IIS / ASP.NET).

Поскольку большая часть информации поступает от веб-службы, которую я вызываю асинхронно, у меня есть IAsyncResult этой операции.

Итак, есть ли способ сказать потоку CLR ThreadPool «Ждать этого IOCP», чтобы поток пула потоков мог начать посещать другой вызов?

У меня такое чувство, что это недостаточно хорошо объяснено, дайте мне знать, если неясно, о чем я спрашиваю.

С Уважением.

PS: Хотя награда закончилась, если кто-нибудь знает, как это сделать, я подниму новую и предоставлю автору.


person vtortola    schedule 28.11.2011    source источник
comment
+1 за хороший и четко объясненный вопрос. Все ли страницы вашего приложения требуют эту информацию или только некоторые из них? Всегда ли первый запрос попадает на определенную страницу или это может быть любая страница?   -  person Darin Dimitrov    schedule 28.11.2011
comment
Спасибо. Только некоторые страницы требовали эту информацию. Учитывая, что домен приложения завершен, и что первый запрос заставляет IIS запустить его, первый запрос не будет аутентифицирован (поскольку мы храним небольшую информацию для входа в объект Session), поэтому первая страница будет страницей для входа в систему.   -  person vtortola    schedule 28.11.2011


Ответы (2)


Это большой вопрос. По моему опыту, чем больше вы пытаетесь вмешиваться во внутреннее устройство ASP.NET, тем больше боли вы причиняете.

Думали ли вы об использовании serviceAutoStartProviders, чтобы ваше приложение оставалось горячим?

ASP.NET 4.0: как использовать класс разминки приложения

person rick schott    schedule 28.11.2011
comment
Это интересно. Но что произойдет, если логика разминки займет много времени? тем временем никто не отвечает на запросы? Возможно, решением было бы придерживаться пулов приложений, но есть ли способ сказать IIS, чтобы он всегда оставался живым? - person vtortola; 29.11.2011
comment
Трудно сказать, такие вещи происходят от случая к случаю. Прежде чем вы сделаете все правильно, потребуется несколько проб и ошибок. - person rick schott; 29.11.2011

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

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

У вас не должно возникнуть проблем, если вы вернетесь из IHttpAsyncHandler за 12 секунд. Фактически, вы можете легко увеличить время до 60 секунд, не беспокоясь. Помимо этого, вам может потребоваться реализовать некоторый тип long- опрос системы для отслеживания состояния системы.

IHttpAsyncHandler может возвращать XML / JSON или что угодно. Вы можете использовать IHttpAsyncHandler через ajax в javascript (возможно, jQuery.ajax) или даже на стороне сервера если вы хотите использовать HttpWebRequest (пример кода C #: Вызов удаленного веб-сервиса JSON).

person BenSwayne    schedule 05.12.2011
comment
Я уже использую AsyncController в MVC, и у меня уже есть IAsyncResult, представляющий IOCP, я хочу сообщить двум или более запросам на ожидание этого IOCP без ожидания вращения, потому что данные общие, и я не хочу получить его более одного раза. - person vtortola; 06.12.2011
comment
@vtortola Тогда вы должны кэшировать данные в памяти в вашем приложении MVC и обслуживать кешированную копию. Это означает, что у вас может быть несколько IAsyncResults, ожидающих, пока кеш получит данные только один раз. Этот вопрос действительно должен касаться медленной архитектуры приложений с большими данными, а не IOCP. Вы не хотите возиться с основами сервера, особенно если вы можете выполнить свою задачу обычными средствами. - person BenSwayne; 06.12.2011