Background task in asp.net core mvc 3.1

别来无恙 提交于 2020-08-05 13:29:13

问题


I want to run a background task in an asp.net core mvc application.

Here is what i've done:

in Startup.cs:

public void ConfigureServices(IServiceCollection services)
{
   ...
   services.AddHostedService<MyTask>();
}

in MyTask.cs:

public class MyTask: BackgroundService
{
   ...
   public override async Task StartAsync(CancellationToken cancellationToken)
   {
      _logger.LogInformation("StartAsync");
   }

   public override async Task StopAsync(CancellationToken cancellationToken)
   {
      _logger.LogInformation("StopAsync");
   }

   ...
}

Here what i've notice: - When i am deploying my website on IIS, i need to hit a page in order to start service - I have notice the Stop is called if i do nothing.

My question is: How to keep alive my application ? I need to run task each minute...

Thanks


回答1:


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.

A timed background task makes use of the System.Threading.Timer class. The timer triggers the task's DoWork method. The timer is disabled on StopAsync and disposed when the service container is disposed on Dispose:

public class TimedHostedService : IHostedService, IDisposable
{
    private int executionCount = 0;
    private readonly ILogger<TimedHostedService> _logger;
    private Timer _timer;

    public TimedHostedService(ILogger<TimedHostedService> logger)
    {
        _logger = logger;
    }

    public Task StartAsync(CancellationToken stoppingToken)
    {
        _logger.LogInformation("Timed Hosted Service running.");

        _timer = new Timer(DoWork, null, TimeSpan.Zero, 
            TimeSpan.FromSeconds(5));

        return Task.CompletedTask;
    }

    private void DoWork(object state)
    {
        var count = Interlocked.Increment(ref executionCount);

        _logger.LogInformation(
            "Timed Hosted Service is working. Count: {Count}", count);
    }

    public Task StopAsync(CancellationToken stoppingToken)
    {
        _logger.LogInformation("Timed Hosted Service is stopping.");

        _timer?.Change(Timeout.Infinite, 0);

        return Task.CompletedTask;
    }

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

The Timer doesn't wait for previous executions of DoWork to finish, so the approach shown might not be suitable for every scenario. Interlocked.Increment is used to increment the execution counter as an atomic operation, which ensures that multiple threads don't update executionCount concurrently.

The service is registered in IHostBuilder.ConfigureServices (Program.cs) with the AddHostedService extension method:

    services.AddHostedService<TimedHostedService>();

To see more detail click below link : Microsoft Documentation




回答2:


This seems to be default behaviour for asp.net. You need to make asp.net app 'always running'. You can do so from the IIS manager aswell as some config files i believe.

There're lots of articles out there on this like: https://www.taithienbo.com/how-to-auto-start-and-keep-an-asp-net-core-web-application-and-keep-it-running-on-iis/

Additionaly i've had success with Hangfire; https://www.hangfire.io/ you can even move the processing of background threads to a different process - even on a different host.

Also see:

https://docs.hangfire.io/en/latest/deployment-to-production/making-aspnet-app-always-running.html




回答3:


Instead of running the background task in you MVC application, perhaps you should run it as a windows service. It is understandable that IIS isn't starting you background task until you hit the first page - that's when it starts your app. Check out https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-3.1&tabs=visual-studio



来源:https://stackoverflow.com/questions/61414044/background-task-in-asp-net-core-mvc-3-1

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!