Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the difference between IHostedService and Task for scheduled task in asp.net core?

I wanna update data from an in-memory database to a relational database every 5 minutes.

Everyone suggests me to use the IHostedService from origin .net core or some other third-party package such as Hangfire.

Whereas, I think it is so troublesome for it must code much.

I have a strange idea that achieves it by the looping task, for example:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
namespace WebApplication3.Controllers
{
    [Route("api/")]
    public class TestController : Controller
    {
        public TestController()
        {
            Task.Run(() => {
                while (true)
                {
                    Console.WriteLine("123");//code something to transfer data to the database
                    Thread.Sleep(5000);
                    //Task.Delay(5000);
                }
            });
        }
        [Route("ABC")]
        public void ABC()
        { 
    }
}
}

What's more, it is so strange that it won't delay any if I use the Task.Delay while it works well if I use the Thread.Sleep.

I wonder why no people achieve it by the Task of System.Threading.Tasks?

Maybe it is a stupid question but I want to find the reason. Thank you.

like image 579
Melon NG Avatar asked Feb 12 '20 07:02

Melon NG


1 Answers

Generally is because of how the process works. I will assume that you don't place the Task.Run() on the controller but on the startup. If you use it on the controller it will simply start a new thread in each and every request.

The way ASP.NET Core works is that it starts a process that listens for incoming request and for each request it creates a new thread for it. Remember that creating a new thread with task run is not the same as something running in the background. In order for it to run on the background you would require a new process not a thread from the thread pool. Generally this will be a thread that will always run and never be freed to server other requests.

What's more, it is so strange that it won't delay any if I use the Task.Delay while it works well if I use the Thread.Sleep.

Use Task.Delay. It requires the async keyword and it doesnt block the thread. You were probably not using the await keyword.

I wonder why no people achieve it by the Task of System.Threading.Tasks?

Generally you could defently implement it but the important thing is the control you have over it. Every 5 minutes your cpu and io usage will spike. But if you split the application in 2 containers in the same host, you can control how much CPU allocation each container will have thus allowing you not to have spikes in performance for the API.

EDIT:

About hosted service as you can see from the documentation ASP.NET Core starts a web server and then starts a IHostedService on a different service. Thats why it's preferred. It's a background task not a thread from the thread pool of your API

EDIT: About the IHostedService I was wrong it doesn't start a new process but you should use it just because it's more manageable and it allows you swap a new process easily and maintain in a much more structured way.

like image 171
A_kat Avatar answered Oct 20 '22 21:10

A_kat