使用ASP.Net核心中间件启动后台任务

Jam*_*s B 6 c# asp.net middleware asp.net-core

我正在尝试在ASP.Net Core中加载页面时运行异步任务,即,我希望任务在用户路由到页面后立即运行,但在任务完成之前显示页面.看来,使用ASP.Net核心,您可以使用中间件来执行此类任务.所以我试图添加以下内容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?}");
            });

}
Run Code Online (Sandbox Code Playgroud)

上面的问题是页面加载有延迟,直到DoAsync完成,因为我们next.Invoke()直到DoAsync完成才调用.我怎样才能正确实现上面的内容,以便next.Invoke()在我DoAsync运行后立即调用?

Pet*_*ter 16

在ASP.NET Core 2中,IHostedService旨在运行您的后台任务.将IHostedService注册为Singleton,它会在启动时自动启动:

实施背景任务功能于微服务与 - ihostedservice和最backgroundservice级净芯-2-X

ASP-净芯背景处理


Alb*_*rtK 5

由于Asp.Net core 2.1使用后台任务,因此IHostedServiceBackgroundService基类派生实现起来非常方便。这是从这里获取的样本:

public class MyServiceA : BackgroundService
{
    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        Console.WriteLine("MyServiceA is starting.");

        stoppingToken.Register(() => Console.WriteLine("MyServiceA is stopping."));

        while (!stoppingToken.IsCancellationRequested)
        {
            Console.WriteLine("MyServiceA is doing background work.");

            await Task.Delay(TimeSpan.FromSeconds(5), stoppingToken);
        }

        Console.WriteLine("MyServiceA background task is stopping.");
    }
}
Run Code Online (Sandbox Code Playgroud)

然后只需将其注册在Startup.ConfigureServices

services.AddSingleton<IHostedService, MyServiceA>();
Run Code Online (Sandbox Code Playgroud)

正如Stephen Cleary所指出的那样,Asp.Net应用程序可能不是执行后台任务的最佳位置(例如,当应用程序托管在IIS中时,由于应用程序池回收,可以将其关闭),但是在某些情况下,它可以很好地应用。


Ste*_*ary 4

ASP.NET不是为后台任务设计的.我强烈建议使用适当的体系结构,例如Azure Functions/WebJobs/Worker Roles/Win32服务/等,并使用可靠的队列(Azure队列/ MSMQ /等)使ASP.NET应用程序与其服务进行通信.

但是,如果您真的想 - 并且愿意接受风险(特别是您的工作可能会被中止),那么您可以使用IApplicationLifetime.

  • @ibubi我从未使用过Quartz.NET.但至少在使用Hangfire时,您需要确保自己的Web应用程序始终保持运行状态.现在它占用了您的网站可能使用的资源,现在您无法将其与您的网站分开扩展.当然,假设您在Web应用程序项目中托管Hangfire.我已经成功地将Hangfire作为一个单独的控制台应用程序托管我作为Windows服务与TopShelf一起运行 - 这消除了缺点,但意味着您需要一个单独的项目来部署. (2认同)