Здесь много разных токенов отмены и несколько разных абстракций (IHostApplicationLifetime
, IHostedService
, BackgroundService
). Требуется время, чтобы распутать все. Сообщение в блоге, на которое вы ссылаетесь, является fantasti c, но не go в деталях на CancellationToken
s.
Во-первых, если вы собираетесь использовать BackgroundService
, я рекомендую чтение кода . Также настоятельно рекомендую не переопределять StartAsync
и StopAsync
; BackgroundService
использует их очень особым образом.
IHostedService
имеет два метода. StartAsync
запускает службу (возможно асинхронно); для этого требуется CancellationToken
, означающее, что операция «запуск» должна быть отменена (я не проверял, но я предполагаю, что этот токен срабатывает только в том случае, если приложение закрывается почти сразу). Обратите внимание, что StartAsync
необходимо завершить , прежде чем размещенная служба будет переведена в состояние «запущено» или «запущено». Точно так же StopAsync
останавливает службу (возможно, асинхронно). StopAsync
вызывается, когда приложение начинает свое постепенное завершение. Есть тайм-аут на период изящного завершения работы, после которого приложение начинает отключение «Я серьезно сейчас». CancellationToken
для StopAsync
представляет переход от «изящного» к «я серьезно сейчас». Таким образом, не устанавливается в течение этого времени изящного отключения.
Если вы используете BackgroundService
вместо IHostedService
напрямую (как большинство людей делают), вы получаете другой CancellationToken
в ExecuteAsync
. Этот устанавливается , когда вызывается BackgroundService.StopAsync
, т.е. когда приложение начало постепенного завершения работы. Таким образом, он примерно эквивалентен IHostApplicationLifetime.ApplicationStopping
, но ограничен одной размещенной службой. Можно ожидать, что BackgroundWorker.ExecuteAsync
CancellationToken
будет установлен вскоре после установки IHostApplicationLifetime.ApplicationStopping
.
Обратите внимание, что все эти CancellationToken
s представляют что-то другое:
IHostedService.StartAsync
s CancellationToken
означает «прервать запуск этой службы». IHostedService.StopAsync
s CancellationToken
означает «остановить эту службу прямо сейчас ; вы вышли из льготный период ". IHostApplicationLifetime.ApplicationStopping
означает" изящная последовательность завершения работы всего этого приложения; всем, пожалуйста, прекратите то, что вы делаете ". - Как часть последовательности изящного отключения, все методы
IHostedService.StopAsync
вызываются.
BackgroundService.ExecuteAsync
's CancellationToken
означает «остановить эту службу».
Интересно отметить, что BackgroundService
типы обычно не видят сигнал "Я серьезно сейчас"; они видят только сигнал «остановить эту услугу». Вероятно, это связано с тем, что сигнал «Я серьезен сейчас», представленный CancellationToken
, несколько сбивает с толку.
Если вы посмотрите на код для Host
, последовательность выключения будет еще больше токены отмены, используемые в последовательности выключения:
IHost.StopAsync
принимает CancellationToken
, что означает "остановка больше не должна быть изящной" . - Затем начинает
CancellationToken
тайм-аут на льготный период . - ... и другой связанный
CancellationToken
, который срабатывает, если либо токен IHost.StopAsync
, либо если таймер истек. Таким образом, этот также означает, что «остановка больше не должна быть изящной». - Далее вызывает
IHostApplicationLifetime.StopApplication
, что отменяет IHostApplicationLifetime.ApplicationStopping
CancellationToken
. - Затем вызывает
StopAsync
для каждого IHostedService
, передавая токен "Стоп больше не должен быть изящным". - Все типы
BackgroundService
имеют свои CancellationToken
(которые были переданы ExecuteAsync
во время запуска), и эти токены отмены отменены StopAsync
.
- Наконец, вызывает
IHostApplicationLifetime.NotifyStopped
, что отменяет IHostApplicationLifetime.ApplicationStopped
CancellationToken
.
Я считаю 3 для сигнала «больше не изящный» (один переданный, один таймер и один связывающий эти два), плюс 2 на IHostApplicationLifetime
, плюс 1 для каждого BackgroundService
, всего 5 + n
токенов отмены, используемых во время выключения , :)