Search code examples
c#.net-coreasp.net-core-webapibackgroundworkerbackground-service

Implementing a long running service (indefinite length / always available) to handle data in an ASP.NET Core Web Api


I'm going to try to simplify this,

As part of an ASP.NET Core Web Api (.Net Core 2.2), I am working to achieve a taxi dispatcher background service that runs indefinitely and handles races -> assigns drivers to races, continuously fetch new drivers on the area and assign to races from closest to furthest accordingly (the service reads and writes to different Sql database tables). I created the background service as a hosted service that does all of the above whenever there are races available and handle each race in a new background thread. The api runs on a ftp server on IIS.

Problem: It works fine at the beginning but sometimes the service somehow times out and won't handle any incoming races and I have to stop the api and restart it, yikes, which isn't the behavior I want since I want my xamarin-forms app to be responsive and receive races in real time.

After I wrote the service, I started questioning my implementation and I came across terms like Background worker, Microservices and Worker services.. and now I'm more confused on what to fix or how to solve the problem, and if there is a better approach to this.

I use clean architecture design pattern in my Web Api. This is how I register my background service on Program.cs file:

        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()
                .ConfigureServices(services =>
                {
                    //Some workaround to use the hostedservice as an API
                    //see https://github.com/dotnet/extensions/issues/553
                    services.AddSingleton<BackgroundManagerService>();
                    services.AddSingleton<IHostedService>(p => p.GetService<BackgroundManagerService>());
                })
                .ConfigureLogging(logging =>
                {
                    logging.ClearProviders();
                    logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace); //LogLevel.Information
                })
                .UseNLog();  // NLog: Setup NLog for Dependency injection;

Help is appreciated!


Solution

  • I ran into similar issues at work using Hangfire. While you can mess around with idle timeouts and app initializers (https://docs.hangfire.io/en/latest/deployment-to-production/making-aspnet-app-always-running.html just as an example) we ultimately moved everything into a .NET Core Worker Service and hosted it as a Windows service.

    https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/windows-service?view=aspnetcore-3.1&tabs=visual-studio

    That is the approach I would suggest, it's worked out very well.