Служба ядра asp.net спит после отсутствия активности API

У меня есть сервис, который проверяет учетную запись электронной почты каждую минуту. Я также использую MVC с Web API 2.1. Чтобы запустить мой размещенный сервис, я должен "разбудить его", вызвав методы API. После периода бездействия веб-API размещенная служба переходит в спящий режим и прекращает проверку электронной почты. Это похоже на сбор мусора. Как мне заставить его работать непрерывно?

Помощь будет принята с благодарностью.

Startup.cs:

public void ConfigureServices(IServiceCollection services)
    {
        services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new Info {Title = "CAS API", Version = "v1"});

                // Set the comments path for the Swagger JSON and UI.
                var xmlFile = $"{Assembly.GetEntryAssembly().GetName().Name}.xml";
                var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
                c.IncludeXmlComments(xmlPath);
            })

            .AddCors(options =>
            {
                options.AddPolicy("CorsPolicy",
                    builder => builder.WithOrigins(Configuration["uiOrigin"])
                        .AllowAnyMethod()
                        .AllowAnyHeader()
                        .AllowCredentials());
            })
            .AddHostedService<EmailReceiverHostedService>()
            .Configure<EmailSettings>(Configuration.GetSection("IncomingMailSettings"))
            .AddSingleton<IEmailProcessor, MailKitProcessor>()
            .AddSingleton<IEmailRepository, EmailRepository>()


          ...

EmailReceiverHostedService.cs:

using CasEmailProcessor.Options;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.Threading;
using System.Threading.Tasks;

public class EmailReceiverHostedService : IHostedService, IDisposable
{
    private readonly ILogger _logger;
    private readonly Timer _timer;
    private readonly IEmailProcessor _processor;
    private readonly EmailSettings _emailConfig;


    public EmailReceiverHostedService(ILoggerFactory loggerFactory,
        IOptions<EmailSettings> settings,
        IEmailProcessor emailProcessor)
    {
        _logger = loggerFactory.CreateLogger("EmailReceiverHostedService");
        _processor = emailProcessor;
        _emailConfig = settings.Value;
        _timer = new Timer(DoWork, null, Timeout.Infinite, Timeout.Infinite);
    }

    public Task StartAsync(CancellationToken cancellationToken)
    {
        _logger.LogInformation("Timed Background Service is starting.");
        StartTimer();
        return Task.CompletedTask;
    }

    public Task StopAsync(CancellationToken cancellationToken)
    {
        _logger.LogInformation("Timed Background Service is stopping.");
        StopTimer();

        return Task.CompletedTask;
    }

    public void Dispose()
    {
        _timer?.Dispose();
    }

    private void StopTimer()
    {
        _timer?.Change(Timeout.Infinite, 0);
    }
    private void StartTimer() { _timer.Change(TimeSpan.FromSeconds(_emailConfig.TimerIntervalInSeconds), TimeSpan.FromSeconds(_emailConfig.TimerIntervalInSeconds)); }

    private void DoWork(object state)
    {
        StopTimer();
        _processor.Process();
        StartTimer();
    }
}

1 ответ

Как вы уже думали, основной причиной является то, что ваш хост может быть отключен из-за перезагрузки пула приложений при размещении в IIS. Это было указано ниже:

Важно отметить, что способ развертывания ASP.NET Core WebHost или.NET Core Host может повлиять на окончательное решение. Например, если вы развернете свой WebHost в IIS или обычной службе приложений Azure, ваш хост может быть отключен из-за перезагрузки пула приложений.

Вопросы развертывания и выводы

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

Из-за повторного использования IIS вы можете рассмотреть различные подходы к хостингу:

  • Используйте службу Windows

  • Используйте Docker Container (Windows Container), но для этого вам понадобится Windows Server 2016 или более поздняя версия.

  • Используйте функции Azure

Для вашего сценария вы можете попробовать Host ASP.NET Core в службе Windows

Я создаю задачу в Windows Event Scheduler для доступа к URL-адресу, чтобы активировать службу.

powershell.exe -command {Invoke-WebRequest http://localhost:8080/}