ASP.NET Core : 十一. 如何在后台运行一个任务

简介: 在大部分程序中一般都会需要用到后台任务, 比如定时更新缓存或更新某些状态。

三、实现方式(二)

在 ASP.NET Core 2.1中, 提供了一个名为 BackgroundService  的类,它在 Microsoft.Extensions.Hosting 命名空间中,查看一下它的源码:

1. 1 using System;
 2 using System.Threading;
 3 using System.Threading.Tasks;
 4 
 5 namespace Microsoft.Extensions.Hosting
 6 {
 7     /// <summary>
 8     /// Base class for implementing a long running <see cref="IHostedService"/>.
 9     /// </summary>
10     public abstract class BackgroundService : IHostedService, IDisposable
11     {
12         private Task _executingTask;
13         private readonly CancellationTokenSource _stoppingCts = new CancellationTokenSource();
14 
15         /// <summary>
16         /// This method is called when the <see cref="IHostedService"/> starts. The implementation should return a task that represents
17         /// the lifetime of the long running operation(s) being performed.
18         /// </summary>
19         /// <param name="stoppingToken">Triggered when <see cref="IHostedService.StopAsync(CancellationToken)"/> is called.</param>
20         /// <returns>A <see cref="Task"/> that represents the long running operations.</returns>
21         protected abstract Task ExecuteAsync(CancellationToken stoppingToken);
22 
23         /// <summary>
24         /// Triggered when the application host is ready to start the service.
25         /// </summary>
26         /// <param name="cancellationToken">Indicates that the start process has been aborted.</param>
27         public virtual Task StartAsync(CancellationToken cancellationToken)
28         {
29             // Store the task we're executing
30             _executingTask = ExecuteAsync(_stoppingCts.Token);
31 
32             // If the task is completed then return it, this will bubble cancellation and failure to the caller
33             if (_executingTask.IsCompleted)
34             {
35                 return _executingTask;
36             }
37 
38             // Otherwise it's running
39             return Task.CompletedTask;
40         }
41 
42         /// <summary>
43         /// Triggered when the application host is performing a graceful shutdown.
44         /// </summary>
45         /// <param name="cancellationToken">Indicates that the shutdown process should no longer be graceful.</param>
46         public virtual async Task StopAsync(CancellationToken cancellationToken)
47         {
48             // Stop called without start
49             if (_executingTask == null)
50             {
51                 return;
52             }
53 
54             try
55             {
56                 // Signal cancellation to the executing method
57                 _stoppingCts.Cancel();
58             }
59             finally
60             {
61                 // Wait until the task completes or the stop token triggers
62                 await Task.WhenAny(_executingTask, Task.Delay(Timeout.Infinite, cancellationToken));
63             }
64         }
65 
66         public virtual void Dispose()
67         {
68             _stoppingCts.Cancel();
69         }
70     }
71 }

可以看出它一样是继承自 IHostedService, IDisposable , 它相当于是帮我们写好了一些“通用”的逻辑, 而我们只需要继承并实现它的 ExecuteAsync 即可。


也就是说,我们只需在这个方法内写下这个服务需要做的事,这样上面的刷新Token的Service就可以改写成这样:

 1     internal class TokenRefreshService : BackgroundService
 2     {
 3         private readonly ILogger _logger;
 4 
 5         public TokenRefreshService(ILogger<TokenRefresh2Service> logger)
 6         {
 7             _logger = logger;
 8         }
 9 
10         protected override async Task ExecuteAsync(CancellationToken stoppingToken)
11         {
12             _logger.LogInformation("Service starting");
13 
14             while (!stoppingToken.IsCancellationRequested)
15             {
16                 _logger.LogInformation(DateTime.Now.ToLongTimeString() + ": Refresh Token!");//在此写需要执行的任务
17                 await Task.Delay(5000, stoppingToken);
18             }
19 
20             _logger.LogInformation("Service stopping");
21         }
22     }

是不是简单了不少。(同样这里为了方便测试写了5秒执行一次)


四. 注意事项

感谢@ 咿呀咿呀哟在评论中的提醒,当项目部署在IIS上的时候, 当应用程序池回收的时候,这样的后台任务也会停止执行。


经测试:


 1. 当IIS上部署的项目启动后,后台任务随之启动,任务执行相应的log正常输出。


 2. 手动回收对应的应用程序池,任务执行相应的log输出停止。


 3. 重新请求该网站,后台任务随之启动,任务执行相应的log重新开始输出。


所以不建议在这样的后台任务中做一些需要固定定时执行的业务处理类的操作,但对于缓存刷新类的操作还是可以的,因为当应用程序池回收后再次运行的时候,后台任务会随着启动。


目录
相关文章
|
9天前
|
开发框架 前端开发 .NET
asp.net core 使用 AccessControlHelper 控制访问权限
asp.net core 使用 AccessControlHelper 控制访问权限
|
21天前
|
Cloud Native API C#
C#的现代化:.NET Core引领的技术革命
【6月更文挑战第9天】`.NET Core引领C#现代化,实现跨平台革命,提升性能并支持云原生应用。异步编程模型优化体验,统一API简化开发流程。C#应用场景扩展,开发效率提高,技术创新加速,预示其未来在技术领域将持续发挥关键作用。`
29 10
|
2天前
|
开发框架 .NET Nacos
使用 Nacos 在 C# (.NET Core) 应用程序中实现高效配置管理和服务发现
使用 Nacos 在 C# (.NET Core) 应用程序中实现高效配置管理和服务发现
9 0
|
3天前
|
存储 JSON NoSQL
技术心得记录:在.NETCore中使用CSRedis
技术心得记录:在.NETCore中使用CSRedis
|
4天前
|
SQL 开发框架 .NET
(20)ASP.NET Core EF创建模型(必需属性和可选属性、最大长度、并发标记、阴影属性)
(20)ASP.NET Core EF创建模型(必需属性和可选属性、最大长度、并发标记、阴影属性)
|
2月前
|
开发框架 前端开发 .NET
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
94 0
|
2月前
|
开发框架 前端开发 JavaScript
JavaScript云LIS系统源码ASP.NET CORE 3.1 MVC + SQLserver + Redis医院实验室信息系统源码 医院云LIS系统源码
实验室信息系统(Laboratory Information System,缩写LIS)是一类用来处理实验室过程信息的软件,云LIS系统围绕临床,云LIS系统将与云HIS系统建立起高度的业务整合,以体现“以病人为中心”的设计理念,优化就诊流程,方便患者就医。
37 0
|
2月前
|
开发框架 前端开发 .NET
C# .NET面试系列六:ASP.NET MVC
<h2>ASP.NET MVC #### 1. MVC 中的 TempData\ViewBag\ViewData 区别? 在ASP.NET MVC中,TempData、ViewBag 和 ViewData 都是用于在控制器和视图之间传递数据的机制,但它们有一些区别。 <b>TempData:</b> 1、生命周期 ```c# TempData 的生命周期是短暂的,数据只在当前请求和下一次请求之间有效。一旦数据被读取,它就会被标记为已读,下一次请求时就会被清除。 ``` 2、用途 ```c# 主要用于在两个动作之间传递数据,例如在一个动作中设置 TempData,然后在重定向到另
156 5
|
2月前
|
开发框架 前端开发 .NET
进入ASP .net mvc的世界
进入ASP .net mvc的世界
|
11月前
|
存储 开发框架 前端开发
[回馈]ASP.NET Core MVC开发实战之商城系统(五)
经过一段时间的准备,新的一期【ASP.NET Core MVC开发实战之商城系统】已经开始,在之前的文章中,讲解了商城系统的整体功能设计,页面布局设计,环境搭建,系统配置,及首页【商品类型,banner条,友情链接,降价促销,新品爆款】,商品列表页面,商品详情等功能的开发,今天继续讲解购物车功能开发,仅供学习分享使用,如有不足之处,还请指正。
137 0