HTTPHandler: IRequiresSessionState останавливает выполнение страниц - PullRequest
3 голосов
/ 22 июля 2010

У меня есть ASHX HTTPHandler, который реализует IRequiresSessionState.Когда я вызываю этот обработчик и вызываю страницу aspx того же приложения в другом окне, страница aspx не начинает обрабатываться, пока страница ashx не завершит обработку.Даже вызов одной и той же страницы Ashx из двух разных окон показывает, что сначала выполняется вызываемая страница, а затем следующая.

Когда я не реализую IRequiresSessionState, страницы загружаются асинхронно, не ожидая завершения другой страницы.

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

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

Другая информация: - Я использую обработчик ashx для обработки и отправки файла, который требует внутреннего сеанса.

Ответы [ 2 ]

4 голосов
/ 25 июля 2010

доступ к состоянию сеанса требует, чтобы страницы aspx и обработчик выполнялись последовательно. Каждая страница / обработчик может читать и записывать в состояние сеанса. Чтобы справиться с этим, не создавая ошибок в состоянии сеанса, .net будет запускаться только по одному за раз. Как предположил Дарин, работа с состоянием сеанса только для чтения улучшит ситуацию. Asp.net позволит нескольким обработчикам работать одновременно, если им требуется только доступ для чтения. Однако для страницы потребуется доступ на запись в сеанс, поэтому никакие обработчики не будут запускаться при запуске самой страницы aspx. Это стандартная схема блокировки одного устройства записи для нескольких устройств чтения. У вас может быть несколько читателей одновременно, но только один писатель.

Единственный способ сделать эту работу - это заставить обработчики не требовать состояния сеанса, чтобы они выполнялись одновременно с запуском страницы aspx.

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

0 голосов
/ 26 июля 2016

Помимо замечаний, высказанных @Mike о IRequiresSessionState, заставляющем каждого «пользователя» (сеанс) обрабатывать только один запрос за раз, есть и другая причина, почему это нужно.

Предположим, у вас есть служба ajax (реализованная с помощью Generic Handler - * .ashx), которая выполняет «обновление» для конкретного пользователя на основе опубликованных данных. Допустим, обновление является тяжелым (около 250 мс) и включает в себя процесс «чтения / слияния / записи» в базу данных (снова данные изолируются для отдельного пользователя). Однако клиент (приложение, веб-сайт и т. Д.) Может выполнять несколько вызовов в быстрой последовательности, которые сервер не может контролировать.

Путем реализации IRequiresSessionState (просто включив его в качестве интерфейса в ваш универсальный обработчик) ASP.NET обеспечит последовательную обработку для данного пользователя / сеанса запросов. Однако несколько пользователей могут параллельно выполнять вызовы для обновления. Это может позволить нам избежать «проблемы с потерянным обновлением», поскольку 2-й запрос не будет извлекать копию данных, пока 1-й запрос не завершит ее обновление.

public class SaveDataHandler : IHttpHandler, IRequiresSessionState
{
    public void ProcessRequest(HttpContext context)
    {
        // Read request parameters
        // Read database (user specific data)
        // Process
        // Write back to database (user specific data)
    }

    public bool IsReusable => false;
}
...