Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

asp.net core hosted service sleeps after api inactivity

I have a hosted service that checks an email account every minute. I also am using MVC with Web API 2.1. In order to get my hosted service to start, I have to "wake it up" by calling API methods. After a period of inactivity from the Web API the hosted service goes to sleep and stops checking the email. It's like it is getting garbage collected. How do I get it to run continuously?

Assistance will be greatly appreciated.

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();
    }
}
like image 849
Cindy Hoskins Avatar asked Sep 19 '18 16:09

Cindy Hoskins


People also ask

What is hosted service in ASP NET Core?

In ASP.NET Core, background tasks can be implemented as hosted services. A hosted service is a class with background task logic that implements the IHostedService interface. This article provides three hosted service examples: Background task that runs on a timer. Hosted service that activates a scoped service.

How do I host an ASP NET Core app on Windows?

An ASP.NET Core app can be hosted on Windows as a Windows Service without using IIS. When hosted as a Windows Service, the app automatically starts after server reboots. The ASP.NET Core Worker Service template provides a starting point for writing long running service apps.

How do I create a service in ASP NET Core?

The ASP.NET Core Worker Service template provides a starting point for writing long running service apps. An app created from the Worker Service template specifies the Worker SDK in its project file: Create a new project. Select Worker Service. Select Next. Provide a project name in the Project name field or accept the default project name.

When hosted as a Windows service the app automatically start?

When hosted as a Windows Service, the app automatically starts after server reboots. The app requires package references for Microsoft.AspNetCore.Hosting.WindowsServices and Microsoft.Extensions.Logging.EventLog.


2 Answers

As you have thought, the root cause is your host can be shut down because of app pool recycle when hosting in IIS. This has been pointed below:

It is important to note that the way you deploy your ASP.NET Core WebHost or .NET Core Host might impact the final solution. For instance, if you deploy your WebHost on IIS or a regular Azure App Service, your host can be shut down because of app pool recycles.

Deployment considerations and takeaways

For a possible workaround, you could try set idle timeout to zero to disable default recycle.

Due to IIS defualt recycle, you may consider the different hosting approcahes:

  • Use a Windows Service

  • Use a Docker Container (Windows Container), but for that, you’d need Windows Server 2016 or later.

  • Use Azure Functions

For your scenario, you could try Host ASP.NET Core in a Windows Service

like image 150
Edward Avatar answered Oct 01 '22 09:10

Edward


I create task on Windows Event Scheduler to access an URL to wakeup the service.

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

like image 37
user3224949 Avatar answered Oct 01 '22 07:10

user3224949