Общая / статическая переменная в Global.asax, изолированная для каждого запроса?

StackOverflow https://stackoverflow.com/questions/62588

  •  09-06-2019
  •  | 
  •  

Вопрос

У меня есть несколько ASP.NET веб-сервисов, которые используют общий вспомогательный класс, им нужно создать только один экземпляр для каждого сервера.Он используется для простого перевода данных, но при запуске тратит некоторое время на загрузку данных из файла web.config и т.д. Вспомогательный класс на 100% потокобезопасен.Думайте об этом как о простой библиотеке служебных вызовов.Я бы сделал все методы общими для класса, но я хочу загрузить начальную конфигурацию из web.config. Мы развернули веб-службы в IIS 6.0 и используем пул приложений с веб-садом из 15 сотрудников.

Я объявил вспомогательный класс как закрытую общую переменную в Global.asax и добавил свойство lazy load Shared ReadOnly, подобное этому:

Private Shared _helper As MyHelperClass

Public Shared ReadOnly Property Helper() As MyHelperClass
    Get
        If _helper Is Nothing Then
            _helper = New MyHelperClass()
        End If
        Return _helper
    End Get
End Property

У меня есть код регистрации в конструкторе для MyHelperClass(), и это показывает конструктор, запущенный для каждого запроса, даже в том же потоке.Я уверен, что мне просто не хватает какой-то ключевой детали ASP.NET но MSDN не очень помог.

Я пробовал делать подобные вещи, используя оба варианта Application("Helper") и Cache("Helper") и я все еще видел, как конструктор запускался при каждом запросе.

Это было полезно?

Решение

неразумно использовать состояние приложения, если вам это абсолютно не требуется, все намного проще, если вы будете придерживаться использования объектов для каждого запроса.Любое добавление state к вспомогательным классам может вызвать всевозможные незначительные ошибки.Используйте коллекцию HttpContext.Current items и инициализируйте ее для каждого запроса.Модуль VB будет делать то, что вы хотите, но вы должны быть уверены, что не делаете его с сохранением состояния.

Другие советы

Вы можете перевести своего Помощника в состояние Приложения.Сделайте это в global.asax:

  void Application_Start(object sender, EventArgs e)
  {
    Application.Add("MyHelper", new MyHelperClass());
  }

Таким образом, вы можете использовать Помощника:

  MyHelperClass helper = (MyHelperClass)HttpContext.Current.Application["MyHelper"];
  helper.Foo();

Это приводит к созданию единственного экземпляра класса MyHelperClass, который создается при запуске приложения и находится в состоянии приложения.Поскольку экземпляр создается в Application_Start , это происходит только один раз для каждого экземпляра HttpApplication, а не для каждого запроса.

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

Никто там не изолирован.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top