Run and manage periodic background tasks in ASP.NET Core 6 with C#

Run and manage periodic background tasks in ASP.NET Core 6 with C#

Sometimes your web app needs to do work in the background periodically e.g. to sync data. This article provides a walkthrough how to implement such a background task and how to enabled/disable a background task during runtime using a RESTful API and hosted services.

Here’s the intro from the Microsoft Docs, read more here:?https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services

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.

Business Logic

So starting from the empy ASP.NET Core 6 template let’s create a simple sample service that represents our business logic that should be invoked by the periodic background tasks. For this demo it’s enough to have a simple method in here to simulate a task and write to the logger.

No alt text provided for this image

Periodic Background Service

Next we need to create the background service that runs a timer for the periodic invocations. This service needs to implement the IHostedService interface in order to registered as a hosted service. To facilitate handling a hosted service we’ll use the BackgroundService base class that handles most of the hosted service house keeping for us and offers the ExecuteAsync method that’s called to run the background service:

No alt text provided for this image

In the ExecuteAsync method we can now add a timer with a while loop. I recommend using the PeriodicTimer as it does not block resources (Read more here?https://www.ilkayilknur.com/a-new-modern-timer-api-in-dotnet-6-periodictimer). The loop shall run while no cancellation of the background service is requested in the CancellationToken and wait for the next tick of the timer:

No alt text provided for this image

It’s a good practise to wrap any invocations inside this while loop into a try catch so that when one run of the while loop fails, it doesn’t break the entire method meaning the periodic loop continues:

No alt text provided for this image

Remember we want to control whether the periodic service is running externally using an API later? So we need a control property and use it in the loop.

No alt text provided for this image

We need to create simple SettingService with flag IsEnabled

Now we can inject SettingService into PeriodicHostedService:

No alt text provided for this image

The last step for our background service is to actually invoke the sample service to execute the business logic. Chances are we want to use a scoped service here. Since no scoped is created for a hosted service by default we need to create one using the IServiceScopeFactory and then get the actual service from the scope. So here is our full class implementation using a scoped service:

No alt text provided for this image


Manage the background service

We need create a SettingsController and inject SettingService, we will have GET and POST route to GET current flag for IsEnabled, and POST for change its value:

No alt text provided for this image
No alt text provided for this image

Note that we inject the background service into each route above? Since it’s not possible to inject a hosted service through dependency injection we need to add this service as a singleton first, then use it for the hosted service registration:

No alt text provided for this image
No alt text provided for this image

We add IServiceCollection extension method where we will registrate?all of our services and hosted jobs in Program.cs class:


Demo

All setup, time to play around!

When starting the app the periodic service will try to execute every 5 seconds as intended but will skip the execution of the business logic as the IsEnabled property is set to false by default.

To enable the background service we need to call the newly created patch route:

No alt text provided for this image
No alt text provided for this image

After this request the service now is enabled and executes the business logic in the SampleService:

No alt text provided for this image

Conclusion

Creating a hosted service and using a timer for periodic updates is straight forward. Just keep in mind you need to create a scope first using the IServiceScopeFactory when you want to use a scoped service in a hosted service and to explicitly add the hosted service as a singleton and using this instance when adding the hosted service to use access the hosted service in a controller/route.

NOTE: When hosting this app e.g. in IIS or Azure App Service make sure the app is set to Always on otherwise the hosted service will be shut down after a while

Please find the full sample solution here:?https://github.com/matijakatadzic/BackgroundTasks.Demo.Net6

要查看或添加评论,请登录

Matija Katadzic的更多文章

  • Send SMS messages with C# & .net6

    Send SMS messages with C# & .net6

    In modern web applications, the business may require to send SMS to end-users in various scopes like Alerting the…

  • Mapping Experiment in .net core- AutoMapper, ExpressMapper, Mapster & Manual mapping

    Mapping Experiment in .net core- AutoMapper, ExpressMapper, Mapster & Manual mapping

    Nuget package that we need: You can read more in official pages: AutoMapper - https://automapper.org/, BenchmarkDotNet…

  • What is a Decorator Pattern?

    What is a Decorator Pattern?

    The decorator pattern (also known as Wrapper) is a structural design pattern and it allows developers to dynamically…

  • What is Strategy Design Pattern?

    What is Strategy Design Pattern?

    Let’s say you are implementing an online eCommerce shop checkout page and you have been told to implement a feature…

  • What is Adapter Design Pattern?

    What is Adapter Design Pattern?

    The Adapter design pattern is one of the most common and useful structural design patterns. It allows objects with…

  • What is a Builder Pattern?

    What is a Builder Pattern?

    Builder Design Pattern allows us to separate the construction of a complex object from its representation so that we…

  • What is Observer Design Pattern?

    What is Observer Design Pattern?

    The Observer is a behavioral design pattern and it allows some objects (known as subjects or publishers or observables)…

  • What’s a design pattern?

    What’s a design pattern?

    Design patterns are typical solutions to commonly occurring problems in software design. They are like pre-made…

  • What is gRPC?

    What is gRPC?

    What is gRPC? gRPC (gRPC Remote Procedure Calls) is an open source remote procedure call (RPC) system initially…

社区洞察

其他会员也浏览了