Преимущества использования фоновых рабочих в ASP. NET, если нет утилизации приложения? - PullRequest
0 голосов
/ 06 апреля 2020

Справочная информация: у меня есть простой ASP. NET Core 3.1 сайт. Очень редко (три или четыре раза в неделю) пользователь может заполнить форму, которая инициирует отправку электронного письма.

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

Я не совсем понимаю, почему это необходимо в modern ASP. NET Core.

Если бы я делал это в обычном C# приложении (не ASP), я бы просто сделал метод 'send email' asyn c (он использует MailKit, который имеет asyn * 1041) * методы) и вызовите метод asyn c без ожидания, позволяя выполнить работу над пулом потоков, в то же время продолжая поток ответов.

Но в существующих ответах и ​​сообщениях блога говорится, что вызов асин * Метод 1043 * без ожидания в ASP опасен из-за того, что IIS может перезапустить ASP процессы (перезапуск пула приложений).

Тем не менее, большинство вещей, которые я прочитал, говорят, что Application Recycling - это артефакт старого ASP, когда утечки памяти были обычным явлением, и это не совсем так. Net Core. Кроме того, многие приложения ASP даже не размещаются в IIS.

Кроме того, насколько я могу судить, объекты IHostedService / Background Worker не делают ничего особенного - они, кажется, не добавляют любая дополнительная нарезка резьбы; они просто выглядят как синглтоны, которые имеют дополнительное уведомление для запуска и завершения среды.

Итак:

  • Вызывает асин c метод пожара и забывания в ASP. NET Ядро все еще считается плохой практикой, особенно если огонь и забыл задача недолговечна? Если так, то почему? [см. правку ниже для пояснения]
  • Кроме уведомлений о завершении работы, есть ли причина, по которой фоновая служба считается лучше, чем заимствование управляемого потока пула потоков (через Task.Run или QueueBackgroundWorkItem)? Разве пробуждение фоновой службы (если она ожидает размещения объекта в коллекции) не потребляет поток пула таким же образом?

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

Возможно, лучший вопрос заключается в том, существует ли старое поведение циклирования в современном ASP (на IIS или Kestrel)? Существуют ли другие причины, по которым может быть запущено правильное завершение работы (кроме выключения сервера / ручной остановки)?

Ответы [ 2 ]

2 голосов
/ 06 апреля 2020

Я бы все равно назвал это плохой практикой.

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

Не зная о побочных фоновых задачах, среда выполнения не сможет уведомить задачи о постепенной остановке. Это может вызывать или не вызывать серьезные проблемы в зависимости от состояния задач в тот момент, когда происходит прекращение.

Использование задачи «забыть о пожаре» часто означает, что ваша задача рискует начать все заново, когда процесс возобновляется. И иногда это невозможно из-за потери контекста. Представьте, что ваша задача «забыть о пожаре» - это вызов другого веб-API с параметрами, предоставленными веб-запросом. Параметры могут быть стерты из памяти, если процесс перезапустится.

И помните, перезапуск не всегда запускается IIS / сервером. Это также может быть вызвано людьми. Скажите, когда ваше приложение сталкивается с проблемой утечки памяти, и вы можете перезапускать процесс приложения каждые 1 час в качестве временного облегчения. Затем вам нужно убедиться, что вы не нарушаете фоновые задачи.

С точки зрения хостинга - все еще возможно разместить ASP. Net Основные приложения внутрипроцессный , в котором пул приложений перерабатывается IIS по истечении заданного периода времени или по умолчанию 29 часов.

С точки зрения срока службы - размещенные службы являются типами, которые вы используете зарегистрируйтесь в DI, чтобы можно было использовать функции DI, например, эта встроенная размещенная служба реализует IDisposable, что означает, что надлежащая очистка может быть выполнена после выключения.

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

1 голос
/ 13 апреля 2020

Чтобы ответить на вторую половину вашего вопроса, приложение будет ждать, пока все методы StopAsync всех размещенных служб не завершат работу sh, прежде чем завершить работу. Пока вы await ваши Task s в размещенной службе, это фактически означает, что вы можете предполагать, что ваши Task s будут допущены к завершению sh, прежде чем приложение закроется. Приложение все еще может быть принудительно завершено, что в этом случае ничего не гарантирует больше.

Если вам нужны дополнительные гарантии относительно фоновых задач, вам следует переместить их для запуска в отдельном процессе. Вы можете использовать что-то вроде Runly , чтобы упростить разбиение функциональности на фоновые задания. Это также упрощает предоставление обратной связи пользователю в режиме реального времени , чтобы вы не лгали пользователю, когда говорите «все сделано», пока что-то еще работает в фоновом режиме.

Полное раскрытие: я основал Runly.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...