консольное приложение dotnet, использующее общий хост, HostedService, планировщик задач Windows остается в рабочем состоянии - PullRequest
0 голосов
/ 26 апреля 2019

Попытка выяснить, почему мое консольное приложение не перестает работать.

Использование следующего подхода в основном методе основного приложения dotnet:

await new HostBuilder().
...
 .ConfigureServices((hostContext, services) =>
  {     
     services.AddHostedService<MyHostedService>(); 
  })
 .UseConsoleLifetime()
 .Build()
 .RunAsync();

Публикация и планирование этой задачи из планировщика задач Windows с использованием следующих настроек:

Windows Task Scheduler settings

Пока все хорошо. Весь код правильно выполнен. Тем не менее, задача продолжает выполняться, процесс никогда не заканчивается (даже после нажатия кнопки «Обновить» в пользовательском интерфейсе планировщика задач)

Это ожидается? Если нет, как заставить процесс завершиться?

Если ожидается, имеет ли смысл использовать Generic Host / Hosted Service в запланированном консольном приложении, которое только запускается, запускается и останавливается?

1 Ответ

1 голос
/ 29 апреля 2019

Ответ основан на Microsoft.Extensions.Hosting 2.2.0

Такое поведение ожидается из-за использования Generic Host :

Он продолжает работать до тех пор, пока не будет отключен или утилизирован, и у вас нет механизма отключения на месте. Я предполагаю, что вы ожидаете, что Generic Host завершит работу после того, как IHostedService.StartAsync (CancellationToken) вашего MyHostedService завершится. Это не так, потому что могут существовать другие IHostedService реализации, зарегистрированные и выполняемые последовательно, и / или долго выполняющаяся BackgroundService , которая возвращает управление, когда ExecuteAsync (CancellationToken) не завершается синхронно, чтобы другие службы могли работать параллельно.

Чтобы корректно остановить ваше приложение после завершения MyHostedService при запуске хоста через RunAsync , вы должны инжектор-конструктор IApplicationLifetime в MyHostedService и позвоните StopApplication после завершения вашей задачи.

internal class MyHostedService : IHostedService
{
    private readonly IApplicationLifetime _appLifetime;

    public MyHostedService(IApplicationLifetime appLifetime)
    {
        _appLifetime = appLifetime;
    }

    public async Task StartAsync(CancellationToken cancellationToken)
    {
        await Task.Delay(1000); //your scheduled work

        _appLifetime.StopApplication();
    }

    public Task StopAsync(CancellationToken cancellationToken)
    {
        return Task.CompletedTask;
    }
}

Кроме того, приложение может быть остановлено с помощью AppDomain.CurrentDomain.ProcessExit или Console.CancelKeyPress , оба события подписаны на ConsoleLifetime , который предварительно зарегистрирован как реализация времени жизни по умолчанию.

Подробнее об управлении временем жизни можно прочитать в документах .

Microsoft.Extensions.Hosting 3.0.0 - в настоящее время в режиме предварительного просмотра - помечен IApplicationLifetime устаревшим и рекомендует использовать IHostApplicationLifetime вместо

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