Search code examples
c#asp.netasp.net-coremiddleware

Start Background Task using ASP.Net Core Middleware


I'm attempting to run an asynchronous task when loading a page in ASP.Net Core, i.e., I want the task to run as soon as the user routes to the page but for the page to be displayed before the task has completed. It seems that with ASP.Net core you use middleware to perform such tasks. So I attempted to add the following to Startup.cs

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IServiceProvider serviceProvider)
        {

// Other configurations here
app.Use(async (context, next) =>
            {
                if (context.Request.Path.Value.Contains("PageWithAsyncTask"))
                {
                    var serviceWithAsyncTask = serviceProvider.GetService<IMyService>();
                    await serviceWithAsyncTask .DoAsync();
                }
                await next.Invoke();
            });

app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });

}

The problem with the above is that there is a delay in the page loading until DoAsync has complete since we don't call next.Invoke() until DoAsync is complete. How do I correctly implement the above such that next.Invoke() is called immediately after I've got DoAsync running?


Solution

  • ASP.NET was not designed for background tasks. I strongly recommend using a proper architecture, such as Azure Functions / WebJobs / Worker Roles / Win32 services / etc, with a reliable queue (Azure queues / MSMQ / etc) for the ASP.NET app to talk to its service.

    However, if you really want to - and are willing to accept the risks (specifically, that your work may be aborted), then you can use IApplicationLifetime.