首页 > 其他分享 >如何使用.NET 6的IHostedService和BackgroundService?

如何使用.NET 6的IHostedService和BackgroundService?

时间:2022-08-22 11:12:33浏览次数:80  
标签:cancellationToken Task BackgroundService NET IHostedService public logger

大家好,我是张飞洪,感谢您的阅读,我会不定期和你分享学习心得,希望我的文章能成为你成长路上的垫脚石,让我们一起精进。

本章是《定制ASP NET 6.0框架系列文章》的第七篇。本文内容和定制无关,主要是关于创建后台服务,用于异步运行任务的功能,我们会使用此功能定期从远程服务获取数据。
本文的主题主要包括:

  • IHostedService介绍
  • BackgroundService介绍
  • Worker Service介绍

1 技术要求

为了演示,我们先创建一个ASP.NET Core应用,我们使用控制台(ShellBash)终端,切换到工作目录,执行以下命令,创建一个MVC应用程序:

dotnet new mvc -n HostedServiceSample -o HostedServiceSample

使用Visual Studio双击打开项目文件,你也可以使用VS Code打开项目,并在已打开的控制台中执行以下命令:

cd HostedServiceSample code .

2 IHostedService介绍

托管服务自ASP.NET Core 2.0开始出现,可在应用后台异步运行任务。比如,可以定期获取数据、在后台进行一些计算或进行一些数据清理。甚至,我们还可以使它发送预配置的电子邮件,或者在后台执行任意的逻辑操作。
托管服务必须实现IHostedService接口,如下代码所示:

public class SampleHostedService : IHostedService {     
    public Task StartAsync(CancellationToken cancellationToken)     {     }     
    public Task StopAsync(CancellationToken cancellationToken)     {     } 
}

IHostedService需要实现StartAsync()StopAsync()方法。StartAsync()是实现要执行的逻辑的地方,该方法在应用程序启动后立即执行,并且只执行一次;StopAsync()方法在应用程序停止之前执行。这意味着要我们需要自己实现一个计划服务,实现一个定期执行代码的循环。
要执行IHostedService,还需要在ASP.NET Core依赖注入容器注册作为单例实例:

builder.Services.AddSingleton<IHostedService, SampleHostedService>();

我们再看下面这个示例,用于展示托管服务的工作方式。它会在启动、停止和每2秒向控制台写入一条日志消息:
首先,我们编写类的骨架,并通过DI反转一个ILogger的实例:

namespace HostedServiceSample; 
public class SampleHostedService:IHostedService {     
    private readonly ILogger<SampleHostedService> logger;        
    public  SampleHostedService(ILogger<SampleHostedService> logger) {                                 
        this.logger = logger;
    }     
    public Task StartAsync(CancellationToken cancellationToken)     
    {}     
    public Task StopAsync(CancellationToken cancellationToken)     
    {} 
}

下一步,实现StopAsync方法。此方法用于需要关闭连接时需要处理的逻辑工作:

public Task StopAsync(CancellationToken cancellationToken) 
{     
    logger.LogInformation("托管服务停止……");     
    return Task.CompletedTask;
}

实际工作将在StartAsync方法内完成:

public Task StartAsync(CancellationToken cancellationToken) {         
    logger.LogInformation("托管服务开始……");     
    return Task.Factory.StartNew(async () => {             
        while (!cancellationToken.IsCancellationRequested) {
            logger.LogInformation($"托管服务执行中 - {DateTime.Now}");             
            try{                 
                //等待2秒                
                await Task.Delay(TimeSpan.FromSeconds(2), cancellationToken); 
            }catch (OperationCanceledException) { } 
        }
     }, cancellationToken); 
}

接下来运行并测试一下,效果如下图所示,日志每2秒写入一次控制台。:

dotnet run

3 BackgroundService介绍

BackgroundService类是在ASP.NET Core 3.0中被引入的,它是一个实现IHostedService接口的抽象类,它还提供了一个名为ExecuteAsync的抽象方法,该方法返回一个Task任务。
我们重写一下上面示例的托管服务,先搭建一个骨架类,如下所示:

namespace HostedServiceSample; 
public class SampleBackgroundService : BackgroundService {     
    private readonly ILogger<SampleHostedService> logger;     
    public SampleBackgroundService(ILogger<SampleHostedService> logger){
        this.logger = logger;     
    }
}

接下来重写StopAsync方法:

public override async Task StopAsync(CancellationToken cancellationToken) {
    logger.LogInformation("后台服务停止……");     
    await Task.CompletedTask; 
}

最后,我们重写ExecuteAsync方法:

protected override async Task ExecuteAsync(CancellationToken cancellationToken) {
    logger.LogInformation("后台服务启动……");     
    await Task.Factory.StartNew(async () =>{         
        while(!cancellationToken.IsCancellationRequested) {
            logger.LogInformation($"后台服务执行中 - {DateTime.Now}");
            try{                 
                await Task.Delay(TimeSpan.FromSeconds(2), cancellationToken);             
            }catch (OperationCanceledException) {}         
        }     
    }, cancellationToken); 
}

注册也要重写一下,在ASP.NET Core 3.0及更高版本中,ServiceCollection有一个新的扩展方法来注册托管服务或后台工作程序:

builder.Services.AddHostedService<SampleBackgroundService>();

在控制台中调用以下命令启动应用程序测试:

dotnet run

测试结果和上头一样,这里不再累述。

4 Worker Service介绍

Worker Service可以叫执行者或者工作者。
ASP.NET Core 3.0及更高版本中,创建简单的工作者服务变得非常容易,这个服务可以也托管在非Web服务器里。
我们再新建一个项目:

dotnet new worker -n BackgroundServiceSample -o BackgroundServiceSample

我们可以看到,该命令会创建一个带有Program.csWorker.cs的控制台应用程序。Worker.cs包含Worker类,它是从BackgroundService类继承的。在ASP.NET 5.0及更早版本,Program.cs文件看起来与以前版本的很相似,但没WebHostBuilder

public class Program {     
    public static void Main(string[] args){         
        CreateHostBuilder(args).Build().Run();     
    }     
    public static IHostBuilder CreateHostBuilder(string[] args)=>
    Host.CreateDefaultBuilder(args).ConfigureServices((hostContext, services) =>{
        services.AddHostedService<Worker>();
    }); 
}

ASP.NET Core 6.0中,Program.cs以与迷你API相同,都被简化掉了。它看起来像这样:

using BackgroundServiceSample; 
IHost host = Host.CreateDefaultBuilder(args).ConfigureServices(services =>{
    services.AddHostedService<Worker>();
}).Build(); 
await host.RunAsync();

这里创建IHost并启用依赖注入,我们可以在任何类型的.NET Core应用程序中使用依赖注入,而不仅仅是在ASP.NET Core应用程序。
然后,我们将工作进程添加到服务集合中,这样就可以将服务作为Windows服务或Docker容器中的后台程序运行。

小结

有了上面的抛砖引玉,现在您可以使用IHostedServiceBackgroundService开始做一些更复杂的事情了。
如果后台服务和应用都在同一个进程中运行,会消耗太多的CPU或内存,甚至降低应用的速度。
所以,对于大型的应用程序,建议单独创建一个用于执行后台任务的应用程序中,可以部署在单独的Docker容器里、或者云服务器里。一定要确保它与主应用程序分开。
在下一章中,我们将进入中间件的学习,以及如何使用中间件在请求管道上实现特殊逻辑,感谢您的阅读。

标签:cancellationToken,Task,BackgroundService,NET,IHostedService,public,logger
From: https://www.cnblogs.com/jackyfei/p/16602676.html

相关文章

  • ASP.NET Core 6框架揭秘实例演示[33]:异常处理高阶用法
    NuGet包“Microsoft.AspNetCore.Diagnostics”中提供了几个与异常处理相关的中间件,我们可以利用它们将原生的或者定制的错误信息作为响应内容发送给客户端。《错误页面的N......
  • 微软Azure配置中心 App Configuration (一):轻松集成到Asp.Net Core
    写在前面在日常开发中,我这边比较熟悉的配置中心有,携程Apollo,阿里Nacos(配置中心,服务治理一体)之前文章:Asp.NetCore与携程阿波罗(Apollo)的第一次亲密接触总体来说,Apo......
  • kubernetes网络排错思想
    Overview本文将引入一个思路:“在Kubernetes集群发生网络异常时如何排查”。文章将引入Kubernetes集群中网络排查的思路,包含网络异常模型,常用工具,并且提出一些案例以供学......
  • asp .net api 接收数组
    publicclassQuestiondetailsDto  {    //publicstring?name{get;set;}    publicList<QuestionDto>list{get;set;}=newList<QuestionD......
  • 浏览器下出现net::ERR_BLOCKED_BY_CLIENT的解决办法
    当我们在做开发时,调试页面图片会出现部分图片无法正常显示,并且确认图片的地址正确;按F12Debug查看报错原因,提示net::ERR_BLOCKED_BY_CLIENT错误,但当我们点击图片地址发现,......
  • ASP.NET CORE在docker中的健康检查(healthcheck)
    在使用docker-compose的过程中,很多程序都提供了健康检查(healthcheck)的方法,通过健康检查,应用程序能够在确保其依赖的程序都已经启动的前提下启动,减少各种错误的发生,同时,合理......
  • Kubernetes学习笔记(十八):命令和参数
    pod-definition.ymlapiVersion:v1kind:Podmetadata:name:ubuntu-sleeper-podspec:containers:-name:ubuntu-sleeperimage:ubuntu-sleeper......
  • ASP.Net Core异步编程
    ASP.NetCore异步编程概念什么是异步编程?异步编程是可以让程序并行运行的一种手段,其可以让程序中的一个工作单元与主应用程序线程分开独立运行,并且在工作单元运行结束后......
  • .NET(C#) 使用Costura.Fody将程序发布成单个exe文件
    Costura是Fody的插件,将依赖项嵌入为资源实现程序发布成单个exe文件。本文主要介绍.NET(C#)中使用Costura.Fody将程序发布成单个exe文件的方法。原文地址:.NET(C#)使用Cos......
  • netcore MongoDB
    NuGet MongoDB.DriverusingMongoDB.Bson;usingMongoDB.Driver;usingSystem;namespaceMongoTest{publicclassMongoHp{staticMongoHp()......