How to create a background task in startup service in asp.net core 1.0 Web API?

I am trying to create a background task to send mails in my Web API. I had created an asynchronous task in a class, and I tried to call it in the constructor, but it doesn't call the method. I want to trigger this class to startup service. Please find the code below:

//Class to call
public class MailClass
{
    public MailClass()
    {
        Task task = Method1();
    }
    public async Task Method1()
    {
        await Task.Run(() =>
        {
            for (int i = 0; i < 100; i++)
            {
                SendMail();
            }
        });
    }
}

/Startup.cs/

    public void ConfigureServices(IServiceCollection services)
   {           
            services.AddMvc();
            services.AddSingleton<MailJob>();
   }

Thanks in advance

Upvotes: 0

Views: 1498

Answers (1)

Chris Pratt
Chris Pratt

Reputation: 239220

There's a lot of issues here. First, async is not background processing. There is no guarantee of a thread-switch, and in a web app context, even if there is a thread-switch, it's still on a threadpool thread, either way. Using Task.Run ensures the work will run on a different thread, but it's still not really "background processing". Again, especially in the context of a web app, you're just taking an additional thread from the pool, which actually hurts your overall server throughput.

If you want to run something in the "background", it should be offloaded to a separate process. Tools like Hangfire enable this. For some reason, every person who is trying to do background work using async, also claims that for some unspecified reason they can't use Hangfire or anything like it. You use the tools you need to get the job done. Period.

However, if you truly can't or won't use something like Hangfire, then you need something like IHostedService. However, that's only available in ASP.NET Core 2.0. It requires very little effort to upgrade, though, and the upgrade is well worth any effort it requires.

Finally, just as an FYI, you can't do async work in a constructor. If you truly need to construct your class with some bit of async functionality, then you need to use something like the static initializer pattern. Essentially, you add an async static method to your class that returns a constructed instance of your class. Then, you can await that.

Upvotes: 1

Related Questions