Вопрос

У меня есть веб-приложение, которое в настоящее время использует текущий 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
}

Однако у меня есть несколько скриптов, которые выполняются из глобального файла.asax, который у меня нет HttpContext. Файл HttpContext. Значение HttpContext.Current равно NULL, потому что сервер - это тот, кто делает "запрос".

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

ОБНОВЛЕННЫЙ:

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

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

Решение

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

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

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

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

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

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

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


Обновить

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

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

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

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

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

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

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

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

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

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