Серверный эквивалент HttpContext? - PullRequest
2 голосов
/ 31 марта 2009

У меня есть веб-приложение, которое в настоящее время использует текущий HttpContext для хранения контекста данных LINQ. Контекст сохраняется для текущего запроса, для каждого пользователя, для блога Рика Страла :

string ocKey = "ocm_" + HttpContext.Current.GetHashCode().ToString("x")  
Thread.CurrentContext.ContextID.ToString();

if (!HttpContext.Current.Items.Contains(ocKey))
{
    // Get new Data Context and store it in the HTTP Context
}

Однако у меня есть несколько сценариев, которые выполняются из файла global.asax, что у нет HttpContext. HttpContext.Current имеет значение NULL , поскольку сервер выполняет запрос.

Есть ли эквивалентный объект, который я могу использовать для хранения контекста данных? Так что мне не нужно беспокоиться о его воссоздании и прикреплении / отсоединении объектов? Я только хочу сохранить контекст для жизни моих процессов.

ОБНОВЛЕНИЕ:

В настоящее время я пытаюсь использовать статическую переменную в своем классе помощника DAL. при первом вызове одного из методов в классе экземпляр DataContext создается и сохраняется в статической переменной. В конце моего процесса я вызываю другой метод, который вызывает Dispose для DataContext и устанавливает для статической переменной значение NULL.

Ответы [ 5 ]

4 голосов
/ 31 марта 2009

Разве вы не можете просто использовать статическую переменную специально для этих скриптов? Это будет иметь то же время жизни, что и AppDomain. Вероятно, вам следует тщательно обдумать любые проблемы параллелизма, но это звучит как самый простой способ сохранить значение.

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

РЕДАКТИРОВАТЬ: ответ Джоша предполагает, что вы хотите, чтобы это было на поток. Это звучит немного странно для меня, поскольку, если у вас нет много этих событий, вы, скорее всего, когда-нибудь увидите, как они выполняются в разных потоках, что делает весь бизнес совместного использования бессмысленным. Если вы действительно хотите такого рода вещи, я бы предложил просто использовать переменную экземпляра в классе HttpApplication - по той причине, которая описана в параграфе выше:)

1 голос
/ 31 марта 2009

Почему бы не использовать текущий HttpContext? Все сценарии в вашем файле global.asax являются результатом запроса, поступающего на сервер, поэтому с этим запросом должен быть контекст, который вы можете получить.

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

Кроме того, как вы избавляетесь от DataContext, когда вы закончите? Он реализует IDisposable по какой-то причине, поэтому я рекомендую использовать общий экземпляр, как этот.


UPDATE

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

0 голосов
/ 01 апреля 2009

Установите DataContext в качестве параметра состояния при создании таймера. На основании информации, которую вы разместили в комментариях, мне кажется, что ваш DataContext больше связан с таймерами, чем с чем-либо еще.

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

0 голосов
/ 31 марта 2009

Есть ли причина, по которой они должны обрабатываться так же, как и другие DataContexts? Мне кажется, что если контекст нужен только внутри подпрограммы обработки событий, вам не нужно его хранить. Особенно, если он находится в Application_Start (согласно вашему комментарию), я бы не стал его где-либо кэшировать - просто используйте его локально и при необходимости передайте другим методам.

0 голосов
/ 31 марта 2009

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

В вашем случае вы не выполняете в контексте запроса. Вы можете посмотреть на использование Application.Cache, но я бы предостерег от сохранения открытого DataContext. Я не очень знаком с linq для сущностей, поэтому могу ошибаться, но обычно кеширование связанных с базой данных элементов, таких как соединения, плохо.

Я бы также рекомендовал вам переместить логику из вашего global.asax в службу windows. Это позволит вам лучше контролировать эти задачи, например, вы можете отключить их отдельно от веб-сайта.

Редактировать

Как указывает JS, вы можете использовать статическую переменную. Вы также можете определить переменную экземпляра, помеченную атрибутом ThreadLocal. Это даст каждому потоку свою собственную копию переменной и может устранить конфликт. Так как вы хотите, чтобы каждый поток имел свою собственную копию в любом случае.

...