Hosting services in .NET Core console application

In .NET Core, the IHost interface is used to configure and run applications, particularly when implementing background services or hosting long-running processes. By using IHostedService, developers can easily manage these services with built-in support for dependency injection, logging, and graceful shutdown.

Key Concepts:

  • IHost: Initializes and configures services for the application.
  • IHostedService: Represents background services with lifecycle management.
  • Graceful Shutdown: Handling cleanup tasks when the application stops.

Example Setup:

public class MyBackgroundService : IHostedService
{
    private readonly ILogger<MyBackgroundService> _logger;

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

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

    public Task StopAsync(CancellationToken cancellationToken)
    {
        _logger.LogInformation("Service stopping...");
        return Task.CompletedTask;
    }
}

Integration:

Using HostBuilder, you can set up services and configure logging:

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureServices((hostContext, services) =>
        {
            services.AddHostedService<MyBackgroundService>();
        });

Best Practices:

  • Exception Handling: Use IHost to manage exceptions and ensure the service doesn’t crash unexpectedly.
  • Dependency Injection: Leverage the built-in DI system to manage dependencies throughout your app.

Unknown's avatar

Author: Peter Groenewegen

Hi, I’m Peter Groenewegen—a technologist, developer advocate, and AI enthusiast passionate about building tools that truly fit people’s workflows. My journey in tech has been one of innovation, collaboration, and a relentless curiosity to make the complex simple.

7 thoughts on “Hosting services in .NET Core console application”

  1. Nice! It’s pretty sweet that we can do this kinda stuff with .Net Core. I’m loving the super flexible ways we can build stuff out now. I remember reading somewhere that you can even launch WCF services from a console using the HostBuilder (not that I would ever want to do that though).
    Just as an extra note, the .net core docs say:
    “If the app shuts down unexpectedly (for example, the app’s process fails), StopAsync might not be called.”
    That’s a pretty important “side-note”. You might want to just put all your “shutdown” logic in the Dispose method, which will always be called, even when the process craps out because of some error (docs again):
    “If an error is thrown during background task execution, Dispose should be called even if StopAsync isn’t called.”
    Thanks Peter! Keep it up!

    Like

    1. Thank you James for the comment, I’m not totally sure how to read the part of the unexpectedly shut down related to the word might. The same goes for Dispose should be called. In that case, who is responsible, the host or the process itself. For graceful shut down I would use the StopAsync and cleaning up the Dispose method. If you have a processing loop that can ‘crash’, it seems a good idea to dispose your disposable resources at the end of the error handling.

      Like

      1. There are some scenarios I have in mind:
        – What if you had a hosted service that needed to inform another system (for whatever reason) that it is going offline (maybe through an api call)?
        – Or perhaps your app is using the hosted service to poll and send updates via SignalR to a UI admin screen that tells you if your app is up and running? If the system is going down (via shutdown or error) you want to send a specific message via SignalR to a client, etc.

        I’m just trying to point out that in a situation like that, developers should be mindful of the fact that using StopAsync will not be as reliable as Dispose. Under certain circumstances (like above) will not have that final necessary action.

        I think developers are going to be using Hosted Services for some very inventive use cases (even though asp had something like it -it’s much easier to use in .net core!) so it’s just something to be mindful of.

        Does that make more sense lol?

        Liked by 1 person

      2. Yes, it does idd make sense. I think it is very ‘implementation’ specific, in most cases where it is important to know the system is running (watchdog), I would prefer to monitor it from outside the process. If there is no response, do the needed actions. However, the difference between stop and disposing can indeed be important in an implementation. Thx for pointing out.

        Liked by 1 person

  2. I’m always looking for a way to abstract the hosting from small “tasks” that I’m building and using IHostedService definitely feels like a step forward, but I’m struggling to determine how to manage a task that is called by an external scheduler (like Azure Functions) and then exits once the task is completed. Perhaps using IHostedService & RunConsoleAsync are not the right fit for this but is there an alternative for tasks where the completion of all hosted service startups (and not Ctrl-C) ends the process? Undoubtedly a shiny new hammer + not really a nail issue but it’s so attractive to have some pattern for configuring & starting tasks independent of what they actually do.

    Like

  3. I am trying to implement this, but some part is very confusing. How RunConsoleAsync() translates to “run as a service”? My problem comes from a requirement to optionally run a long process as Service or Console App. I was thinking in something like RunServiceAsync() and RunConsoleAsync() controlled by a parameter… but as RunAsConsoleAsync() means “run as service”, I’m confused.
    Thanks for any suggestion

    Like

    1. “RunConsoleAsync()” doesn’t run the application as a service – it runs it as a console executable.
      Within that executable, you can create an IHostedService. Quoting the article:
      “You can run multiple IHostedService in one host.”
      So the host could be a console app (like in this case), a web app or even a windows service if you want. IHostedService isn’t a Windows service – it’s a background service specifically within an existing application.
      So these are two different things. IHostedServices are just background jobs that can be kept alive for the entirety of your application and can be “told” when the app is shutting down.
      Hopefully that helps 🙂

      Liked by 1 person

Leave a reply to JamesPWhite Cancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.