前言
在进行基于钉钉的H5微应用开发时,会遇到这样的业务场景:需要定时刷接口获取access_token,这是一个调用接口的凭证,本且有效期是两个小时,在过期后我们需要定时去请求获取该token,否则就无法调用接口服务。于是,就有了后台任务的需求。
本文应该算是钉钉H5微应用开发系列的一个补充知识。
如何实现?
前提条件:使用NUGET添加Microsoft.Extensions.Hosting包到项目中。
主角:IHostedService接口
托管服务必须实现IHostedService接口,该接口为主机管理的对象定义了两种方法。
StartAsync(CancellationToken) - StartAsync包含启动后台任务的逻辑。使用Web主机时,StartAsync在服务器启动并且触发IApplicationLifetime.ApplicationStarted后调用。使用Generic Host时,StartAsync会在ApplicationStarted触发之前调用。
实现步骤
(1)业务类继承BackgroundService
BackgroundService 是用于实现长时间运行的 IHostedService 的基类。调用 ExecuteAsync(CancellationToken) 来运行后台服务。 实现返回一个 Task,其表示后台服务的整个生存期。业务类继承该接口可以
实现方法:
Dispose() | |
Equals(Object) | 确定指定的对象是否等于当前对象。 (继承自 Object) |
ExecuteAsync(CancellationToken) | 此方法在启动 IHostedService 时调用。 该实现应返回一个任务,该任务表示正在执行的长时间运行的操作的生存期。 |
GetHashCode() | 作为默认哈希函数。 (继承自 Object) |
GetType() | 获取当前实例的 Type。 (继承自 Object) |
MemberwiseClone() | 创建当前 Object 的浅表副本。 (继承自 Object) |
StartAsync(CancellationToken) | 当应用程序主机准备好启动服务时触发。 |
StopAsync(CancellationToken) | 当应用程序主机执行正常关闭时触发。 |
ToString() | 返回表示当前对象的字符串。 (继承自 Object) |
实例代码:
internal class TokenRefreshService : BackgroundService
{
private readonly ILogger _logger;
public TokenRefreshService(ILogger<TokenRefresh2Service> logger)
{
_logger = logger;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
_logger.LogInformation("Service starting");
while (!stoppingToken.IsCancellationRequested)
{
_logger.LogInformation(DateTime.Now.ToLongTimeString() + ": Refresh Token!");
//业务逻辑的书写。。。
DosomeThing(){
...
}
await Task.Delay(5000, stoppingToken);
}
_logger.LogInformation("Service stopping");
}
}
(2)注入服务
在 Startup 的 ConfigureServices 注册
services.AddHostedService<TokenRefreshService>()
一个问题
当项目部署在IIS上的时候, 当应用程序池回收的时候,后台任务是否也会也会停止执行?
答:部署在iis上时选择了无托管代码形式,以往的.net会存在应用程序集回收的情况,在.net core中不会。