Почему завершение сеанса пользователя asp.net вызывает завершение задачи Quartz в другом пуле приложений? - PullRequest
0 голосов
/ 04 мая 2019

Я использую C # с планировщиком Quartz в приложении asp.net.После того, как пользователь нажимает кнопку на внешнем интерфейсе, задача Quartz немедленно запускается в фоновом режиме, однако эта задача преждевременно завершается после завершения сеанса пользователя.

Сеанс пользователя - это пул приложений, отличный от пула сеанса Quartz.

Очевидно, что желаемое поведение для продолжения задачи, даже когда пользователь, инициировавший задачу, завершает свою работу или завершает сеанс.

Обновление: я добавил больше журналовинформация - что на самом деле вызывает остановку задачи, это:

в System.Web.Hosting.HostingEnvironment.StopRegisteredObjects (немедленное логическое значение) в System.Web.Hosting.HostingEnvironment.InitiateShutdownWorkItemCallback (состояние объекта) в системе.Threading.ExecutionContext.RunInternal (ExecutionContext executeContext Execution, обратный вызов ContextCallback, состояние объекта, Boolean preserveSyncCtx) в System.Threading.ExecutionContext.Run (обратный вызов ExecutionContext executeContext, обратный вызов ContextCallback, состояние объекта, логический preserveSynct)System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem () в System.Threading.ThreadPoolWorkQueue.Dispatch ()

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


Сначала я думал, что проблема связана с областью действия Autofac Lifetime компонента иМой вопрос изначально был сосредоточен на этом.Я оставлю свои замечания по Autofac ниже, потому что может оказаться, что это был фактор, я просто пока не знаю, пока не решу проблему.

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

Поскольку существует много зависимостей, я подумал, что если я проверю внутренний код Autofac в отладчике, это поможет мне определить, что быловызывая проблему.

Однако мне трудно понять, как внутренняя область действия представлена ​​внутри Autofac.

Кто-нибудь знает, как найти область действия, связанную с компонентом в Autofac, в частности, если у него есть область действия запроса?

Ответы [ 2 ]

0 голосов
/ 08 мая 2019

Пул приложения-службы был настроен по требованию с временем ожидания простоя 20 минут - вот почему выглядело, как будто пользовательский сеанс поддерживал выполнение задачи.Изменение пула приложений-служб на постоянное выполнение и установка времени простоя на 0 решило проблему.

0 голосов
/ 06 мая 2019

Я вроде получаю то, что вы ищете, но я не уверен, что знание того, как жизненный объем работает «внутренне», вполне поможет. Возможно, вам просто поможет понять, как концептуально работают области и как родительские области относятся к дочерним областям. Вокруг этого есть документация.

Если вы на самом деле хотите знать, как "жизненный объем" "представлен внутренне", вам лучше всего просмотреть источник. Начните с ContainerBuilder.Build, который создает новый Container (который сам по себе имеет область действия - «область действия корневого ресурса»). Затем посмотрите, как работает LifetimeScope, разрешая компоненты из реестров.

Но, как я уже сказал, я не думаю, что это поможет вам так же, как концепции.

Без Минимального, полного и проверяемого примера Я не могу сказать вам, где вы идете не так; и нет сообщения об ошибке, указывающего, как мы можем помочь; но я догадываюсь это:

  • Ваше приложение запускается и создает контейнер.
  • Фоновая задача запускается либо на основе чего-то, разрешенного из контейнера (вероятно, не очень хорошо с , что может вызвать утечки памяти для одноразовых компонентов ), либо запускается из дочерней области. Если дочерняя область, в которой запускается фоновая задача, является областью запроса, это проблема - Эта область запроса будет удалена после выполнения данного HTTP-запроса. Если это не объем запроса, хорошо.
  • Приходит запрос, и контроллер в вашем приложении MVC (или что-то еще) генерируется на основе области действия времени запроса. Вы выполняете некоторую работу и, основываясь на чем-то в контроллере (возможно, разрешенной зависимости), вы передаете это чему-то, что передает это чему-то другому, что в конечном итоге оказывается в фоновой задаче. Если вы передаете фоновой задаче что-то, что существует из-за объема запроса, это плохо. Если это не простой объект данных (без состояния, без IDisposable и т. Д.), То вы можете избавиться от вещей. из-под вас, когда запрос заканчивается.

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

Вот что я бы посмотрел на , если бы я отлаживал что-то вроде этого:

  • Решена ли фоновая задача или какая-либо из ее зависимостей из области действия запроса? Проверьте фактические регистрации. Если у вас есть InstancePerRequest где-нибудь, это не хорошо. Если у вас есть InstancePerLifetimeScope, это может или не может быть хорошо - InstancePerLifetimeScope может означать, что вы получаете что-то из области запроса вместо, скажем, корневого контейнера.
  • Действие, которое выполняется, когда «сеанс, инициировавший задачу, заканчивается» - это получение некоторой информации, полученной из области запроса? Было ли это решено как-то? Из базы данных или что-то в этом роде? Может ли контекст базы данных, переданный контроллеру MVC (или какому-либо другому), закрывать соединение из-под объекта данных, связанного с работой фоновой задачи?

Возможно, вас также заинтересует этот пакет Autofac.Analysis, который регистрирует события Autofac в Serilog. Я не могу поручиться за него сам, но он может дать некоторую полезную информацию.

Надеюсь, это поможет. Если нет, то, по крайней мере, возможно, это поможет вам понять, с чего начать. Опять же, я не думаю, что понимание того, как область действия представлена ​​внутри Autofac, поможет вам, но, возможно, концепции помогут.

...