api不活动后,asp.net核心托管服务进入休眠状态

时间:2018-09-19 16:52:46

标签: asp.net-core asp.net-core-webapi asp.net-core-2.1 asp.net-core-hosted-services

我有一个托管服务,每分钟检查一次电子邮件帐户。我还将MVC与Web API 2.1一起使用。为了启动我的托管服务,我必须通过调用API方法来“唤醒”它。 Web 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();
    }
}

2 个答案:

答案 0 :(得分:3)

如您所想,根本原因是由于在IIS中进行托管时,由于应用程序池回收,您的主机可能被关闭。这已在下面指出:

  

请务必注意,部署ASP.NET Core WebHost或.NET Core Host的方式可能会影响最终解决方案。例如,如果您将WebHost部署在IIS或常规的Azure App Service上,则由于应用程序池回收,主机可能会被关闭。

Deployment considerations and takeaways

对于一个可能的解决方法,您可以尝试将空闲超时设置为零以禁用默认回收。

由于IIS的默认回收,您可以考虑使用不同的托管方法:

  • 使用Windows服务

  • 使用Docker容器(Windows容器),但为此,您需要Windows Server 2016或更高版本。

  • 使用Azure功能

对于您的情况,您可以尝试Host ASP.NET Core in a Windows Service

答案 1 :(得分:0)

我在Windows Event Scheduler上创建任务以访问URL来唤醒服务。

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