Метод HttpModule Init несколько раз называют - почему?

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

31
задан MartinF 17 July 2009 в 13:31
поделиться

4 ответа

  1. Просмотрите HttpContext.Current.Request, чтобы узнать, для какого запроса запускается инициализация модуля. Возможно, браузер отправляет несколько запросов.

  2. Если вы подключены к IIS, обязательно проверьте журналы IIS, чтобы узнать, получен ли какой-либо запрос за то время, пока вы находитесь в точке останова.

8
ответ дан 27 November 2019 в 22:20
поделиться
2
ответ дан 27 November 2019 в 22:20
поделиться

Метод Init () вызывается несколько раз - это нормально. Когда приложение запускается, рабочий процесс ASP.NET создает столько объектов HttpApplication, сколько считает нужным, а затем объединяет их (например, повторно использует их для новых запросов, аналогично пулу соединений с базой данных).

Теперь для каждого объекта HttpApplication он также будет создавать экземпляр каждого зарегистрированного модуля IHttpModule и многократно вызывать метод Init. Итак, если будет создано 5 объектов HttpApplication, будет создано 5 копий вашего IHttpModule, а ваш метод Init будет вызван 5 раз. Имеет смысл?

Теперь, почему он создает экземпляры 5 объектов HttpApplications, говорят? Что ж, возможно, ваша страница ASPX имеет ссылки на другие ресурсы, которые ваш браузер попытается загрузить, css, javascript, WebResource.aspx, может быть, где-то iframe. Или, может быть, рабочий процесс ASP.NET «находится в настроении» для запуска более 1 объекта HttpApplication, что на самом деле является внутренней деталью / оптимизацией процесса ASP.NET, работающего под IIS (или VS, встроенного в веб-сервер).

Если вам нужен код, который гарантированно запускается только один раз (и вы не хотите использовать событие Application_StartUp в Global.asax), вы можете попробовать следующее в своем IHttpModule:

private static bool HasAppStarted = false;
private readonly static object _syncObject = new object();

public void Init(HttpApplication context)
{
    if (!HasAppStarted)
    {
        lock (_syncObject)
        {
            if (!HasAppStarted)
            {
                // Run application StartUp code here

                HasAppStarted = true;
            }
        }
    }
}

Я сделал нечто подобное и похоже, это работает, хотя я бы приветствовал критику моей работы, если я что-то пропустил.

42
ответ дан 27 November 2019 в 22:20
поделиться

Пример выше блокирует IHttpModule для всех запросов, а затем блокирует все приложение. Если ваш IHttpModule вызывает запрос несколько раз, необходимо вызвать метод HttpApplication CompleteRequest и удалить экземпляр HttpApplication IHttpModule в событии EndRequest, чтобы удалить экземпляр HttpApplication следующим образом:

public class TestModule :IHttpModule
    {
        #region IHttpModule Members

        public void Dispose()
        {

        }

        public void Init(HttpApplication context)
        {
            context.BeginRequest += new EventHandler(context_BeginRequest);
            context.EndRequest += new EventHandler(context_EndRequest);
        }

        void context_EndRequest(object sender, EventArgs e)
        {
            HttpApplication app = sender as HttpApplication;
            app.CompleteRequest();
            app.Dispose();
        }

        void context_BeginRequest(object sender, EventArgs e)
        {
            //your code here
        }

        #endregion
    }

Если вам нужно, чтобы IHttpModule запрашивал каждый раз без повторного запроса при обратной передаче используйте этот код выше.

1
ответ дан 27 November 2019 в 22:20
поделиться
Другие вопросы по тегам:

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