Asp.net core Webapi 如何执行定时任务?

前言
在计算机系统中,定时执行一些后台任务是很常见的场景,比如定时发送邮件、备份数据等等。
那么,.NET 技术如何通过编程灵活地实现项目里复杂的自定义任务呢?
如果是 Windows 生态,通常来说,可以有这些方式:
- 编写一个程序,通过 Windows 内置的任务计划来定时执行。
- 编写一个程序,通过 Windows 内置的 Services 来定时执行。
- 编写一个定时循环执行任务的程序,在 Windows 系统启动时配置为自动执行。
……
但是,如果是一个中小型的 Web 应用系统,这些方法方式就显得不太合适。Asp.net core Webapi 有没有办法执行定时任务呢?答案是有的,Asp.net core Webapi 可以通过常驻后台的托管服务来执行定时任务。
本文是 Asp.net core Webapi 运行一个常驻后台并从数据库中导出数据的托管服务的例子,写出来供大家指点,在讨论过程中共同提高水平。
Step By Step 实现步骤
- 创建一个 asp.net core webapi 项目
- 从 Nuget 安装以下包
Microsoft.AspNetCore.Identity.EntityFrameworkCore
Microsoft.EntityFrameworkCore.Relational
Microsoft.EntityFrameworkCore.SqlServer
Microsoft.EntityFrameworkCore.Tools - 打开 appsettings.json 并添加数据库连接字符串,如:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"Default": "Server=(localdb)\\mssqllocaldb;Database=IdentityTestDB;Trusted_Connection=True;MultipleActiveResultSets=true"
}
}
- 添加一个继承于 IdentityUser 的 User 类
using Microsoft.AspNetCore.Identity; public class User: IdentityUser<long>
{
public DateTime CreationTime { get; set; }
public string? NickName { get; set; }
}
- 添加一个继承于 IdentityRole 的 Role 类
using Microsoft.AspNetCore.Identity; public class Role: IdentityRole<long>
{ }
- 创建数据库上下文
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore; public class TestDbContext: IdentityDbContext<User, Role, long>
{
public TestDbContext(DbContextOptions<TestDbContext> options):base(options)
{ } protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.ApplyConfigurationsFromAssembly(this.GetType().Assembly);
}
}
- 创建一个 ExplortStatisticBgService 类并继承 BackgroundService,这是托管服务类
using Microsoft.EntityFrameworkCore;
using System.Text; public class ExplortStatisticBgService : BackgroundService
{
private readonly TestDbContext ctx;
private readonly ILogger<ExplortStatisticBgService> logger;
private readonly IServiceScope serviceScope; /// <summary>
/// 在构造方法注入IServiceScopeFactory服务,
/// 用来创建IServiceScope对象,
/// 这样就可以通过IServiceScope来创建短生命周期的服务了
/// </summary>
/// <param name="scopeFactory"></param>
public ExplortStatisticBgService(IServiceScopeFactory scopeFactory)
{
this.serviceScope = scopeFactory.CreateScope();
var sp = serviceScope.ServiceProvider;
this.ctx = sp.GetRequiredService<TestDbContext>();
this.logger = sp.GetRequiredService<ILogger<ExplortStatisticBgService>>();
} protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
// 用 while 循环实现服务常驻
while (!stoppingToken.IsCancellationRequested)
{
// 用 try...catch 捕捉异常记录错误信息并避免方法退出
try
{
// 这里实现每隔5秒从数据库中导出数据
// 更复杂的配置可以用第三方开源的框架
await DoExecuteAsync();
await Task.Delay(5000);
}
catch (Exception ex)
{
logger.LogError(ex, "获取用户统计数据失败");
await Task.Delay(1000);
}
}
} private async Task DoExecuteAsync()
{
var items = ctx.Users.AsNoTracking().GroupBy(u => u.CreationTime.Date)
.Select(e => new
{
Date = e.Key,
Count = e.Count()
});
StringBuilder sb = new StringBuilder(1024);
sb.AppendLine($"Date: {DateTime.Now}");
foreach (var item in items)
{
sb.Append(item.Date).AppendLine($": {item.Count}");
}
await File.WriteAllTextAsync("d:/1.txt", sb.ToString());
logger.LogInformation($"导出完成");
} /// <summary>
/// IServiceScope 需要释放
/// 所以重写 Dispose 方法
/// </summary>
public override void Dispose()
{
base.Dispose();
serviceScope.Dispose();
}
}
- 打开 Program.cs,注入托管服务等,看代码的注释
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore; var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(); IServiceCollection services = builder.Services; // 注册托管服务
services.AddHostedService<ExplortStatisticBgService>(); // 注入数据库上下文
services.AddDbContext<TestDbContext>(options => {
string connStr = builder.Configuration.GetConnectionString("Default")!;
options.UseSqlServer(connStr);
}); // 数据保护服务注入
// ----数据保护提供了一个简单、基于非对称加密改进的加密API用于确保Web应用敏感数据的安全存储
// ----不需要开发人员自行生成密钥,它会根据当前应用的运行环境,生成该应用独有的一个私钥
services.AddDataProtection(); // 注入 Identity 框架的一些重要的基础配置
// 如果没有这个,下面的注入 UserManager 等服务会有问题,程序无法编译
services.AddIdentityCore<User>(options =>
{
options.Password.RequireDigit = false;
options.Password.RequireLowercase = false;
options.Password.RequireNonAlphanumeric = false;
options.Password.RequireUppercase = false;
options.Password.RequiredLength = 6;
options.Tokens.PasswordResetTokenProvider = TokenOptions.DefaultEmailProvider;
options.Tokens.EmailConfirmationTokenProvider = TokenOptions.DefaultEmailProvider;
}); // 注入 UserManager、RoleManager 等Identity 框架服务
var idBuilder = new IdentityBuilder(typeof(User), typeof(Role), services);
idBuilder.AddEntityFrameworkStores<TestDbContext>()
.AddDefaultTokenProviders()
.AddRoleManager<RoleManager<Role>>()
.AddUserManager<UserManager<User>>(); var app = builder.Build(); // Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
} app.UseHttpsRedirection(); app.UseAuthorization(); app.MapControllers(); app.Run();
``
- Ctrl+F5 运行项目,不做任何操作,托管程序会自动导出数据
扩展
托管服务在后台运行,通过它可以实现在很多事情,比如:
- 监控消息队列,当有数据进入消息队列就处理。
- 再如每隔10s把A数据库中的数据同步到B数据库中
- ...... 等等
Asp.net core Webapi 如何执行定时任务?的更多相关文章
- ASP.Net Core WebApi几种版本控制对比
版本控制的好处: (1)助于及时推出功能, 而不会破坏现有系统. (2)它还可以帮助为选定的客户提供额外的功能. API 版本控制可以采用不同的方式进行控制,方法如下: (1)在 URL 中追加版本或 ...
- ASP.NET Core WebApi使用Swagger生成api说明文档看这篇就够了
引言 在使用asp.net core 进行api开发完成后,书写api说明文档对于程序员来说想必是件很痛苦的事情吧,但文档又必须写,而且文档的格式如果没有具体要求的话,最终完成的文档则完全取决于开发者 ...
- ASP.NET Core WebApi使用Swagger生成api
引言 在使用asp.net core 进行api开发完成后,书写api说明文档对于程序员来说想必是件很痛苦的事情吧,但文档又必须写,而且文档的格式如果没有具体要求的话,最终完成的文档则完全取决于开发者 ...
- ASP.NET Core WebApi使用Swagger生成api说明文档
1. Swagger是什么? Swagger 是一个规范和完整的框架,用于生成.描述.调用和可视化 RESTful 风格的 Web 服务.总体目标是使客户端和文件系统作为服务器以同样的速度来更新.文件 ...
- asp.net core webapi 使用ef 对mysql进行增删改查,并生成Docker镜像构建容器运行
1.构建运行mysql容器,添加数据库user 参考Docker创建运行多个mysql容器,地址 http://www.cnblogs.com/heyangyi/p/9288402.html 添加us ...
- Docker 为 ASP.NET Core WebApi 应用程序生成 Docker 映像,创建容器并运行
1.使用VS2017新建ASP.NET Core WebApi项目 选择API启用Docker支持 2.为 ASP.NET Core WebApi 应用程序生成 Docker 映像,并创建容器运行 生 ...
- 【转】ASP.NET Core WebApi使用Swagger生成api说明文档看这篇就够了
原文链接:https://www.cnblogs.com/yilezhu/p/9241261.html 引言 在使用asp.net core 进行api开发完成后,书写api说明文档对于程序员来说想必 ...
- ASP.NET CORE WEBAPI文件下载
ASP.NET CORE WEBAPI文件下载 最近要使用ASP.NET CORE WEBAPI用来下载文件,使用的.NET CORE 3.1.考虑如下场景: 文件是程序生成的. 文件应该能兼容各种格 ...
- ionic + asp.net core webapi + keycloak实现前后端用户认证和自动生成客户端代码
概述 本文使用ionic/angular开发网页前台,asp.net core webapi开发restful service,使用keycloak保护前台页面和后台服务,并且利用open api自动 ...
- 记一次使用Asp.Net Core WebApi 5.0+Dapper+Mysql+Redis+Docker的开发过程
#前言 我可能有三年没怎么碰C#了,目前的工作是在全职搞前端,最近有时间抽空看了一下Asp.net Core,Core版本号都到了5.0了,也越来越好用了,下面将记录一下这几天以来使用Asp.Net ...
随机推荐
- Java程序员学vue3最好的方式就是搭建后台管理模板
前言 作为Java程序员,vue3还是有必要学的,毕竟是国内最受欢迎的前端JS框架,你现在接手的项目,前端部分几乎都会和vue沾边,尤其是中小企业. vue3作为新的大版本,相较于vue2改动还是很多 ...
- 【SpringBoot实战】开发入门--快速创建springboot程序
前言 本片博客记录快速创建springboot工程的使用spring initializr创建.开发环境JDK1.8.IDEA.maven. SpringBoot 优点 可快速构建spring应用 直 ...
- SpringBoot + Redis + Token 解决接口幂等性问题
前言 SpringBoot实现接口幂等性的方案有很多,其中最常用的一种就是 token + redis 方式来实现. 下面我就通过一个案例代码,帮大家理解这种实现逻辑. 原理 前端获取服务端getTo ...
- 2023-09-16:用go语言,给你一个整数 n 和一个在范围 [0, n - 1] 以内的整数 p , 它们表示一个长度为 n 且下标从 0 开始的数组 arr , 数组中除了下标为 p 处是 1
2023-09-16:用go语言,给你一个整数 n 和一个在范围 [0, n - 1] 以内的整数 p , 它们表示一个长度为 n 且下标从 0 开始的数组 arr , 数组中除了下标为 p 处是 1 ...
- JavaAgent寄生在目标进程中引起的ClassNotFoundException
今天有解决方案部的小伙伴反映,我公司XWind产品在分析客户应用程序的潜在性能问题时,总是显现诊断任务异常,为了定位问题的根因,我们马上要求解决方案部的小伙伴提供XWind相关的日志,从日志中找到了如 ...
- 小米手机抓取Log教程
当小米手机遇到任何系统下的较为严重的故障时(即此时系统还是基本正常运行的,只是某些功能实现出了问题),例如软件自动退出,SD卡自动卸载,电话无法拨出等等.可以请用户协助抓取log即系统运行日志,来发送 ...
- 几个易错的python小知识点
大家好,我是暴走の海鸽~ 本期整理了几个基础python防坑小常识,希望对大家有所帮助. 1. type == object? 执行以下代码的结果是什么: >>> isinstanc ...
- Substring of Sorted String 题解
Substring of Sorted String 写篇题解纪念一下蒟蒻第一次赛时切出的 F 题. 题目简述 对一个字符串进行单点修改,区间判断操作. 修改操作为将一个字符修改为另一个,判断操作为判 ...
- 关于Halcon中variation_model模型的快速解读。
十一期间在家用期间研读了下Halcon的variation_model模型,基本上全系复现了他的所有技术要求和细节,这里做个记录. 其实这个模型的所有原理都不是很复杂的,而且Halcon中的帮助文档也 ...
- 如何去掉桌面快捷方式左下角的小箭头(Win11)
在对系统重命名之后,在快捷方式的左下角莫名的出现了小图标 如果想要去掉这个小图标 (1)首先在桌面上创建一个txt文件 (2)打开后输入指令 reg add "HKEY_LOCAL_MACH ...