如果我们想要在Web Api服务中创建一个定制任务后台一直刷新执行某些操作,那么我们可以继承abstract抽象类HostedService,具体操作如下:
BackgroundService.cs源代码,这个源代码我可以自己写一个也可以直接继承。
/// <summary>
/// 自定义BackgroundService
/// </summary>
public abstract class BackgroundService : IHostedService, IDisposable
{
#pragma warning disable CS8625 // 禁用CS8625警告
private Task _executingTask = null;
private readonly CancellationTokenSource _stoppingCts = new CancellationTokenSource();
#pragma warning restore CS8625 // 恢复CS8625警告
/// <summary>
/// This method is called when the <see cref="IHostedService"/> starts. The implementation should return a task that represents
/// the lifetime of the long running operation(s) being performed.
/// </summary>
/// <param name="stoppingToken">Triggered when <see cref="IHostedService.StopAsync(CancellationToken)"/> is called.</param>
/// <returns>A <see cref="Task"/> that represents the long running operations.</returns>
protected abstract Task ExecuteAsync(CancellationToken stoppingToken);
/// <summary>
/// Triggered when the application host is ready to start the service.
/// </summary>
/// <param name="cancellationToken">Indicates that the start process has been aborted.</param>
public virtual Task StartAsync(CancellationToken cancellationToken)
{
// Store the task we're executing
_executingTask = ExecuteAsync(_stoppingCts.Token);
// If the task is completed then return it, this will bubble cancellation and failure to the caller
if (_executingTask.IsCompleted)
{
return _executingTask;
}
// Otherwise it's running
return Task.CompletedTask;
}
/// <summary>
/// Triggered when the application host is performing a graceful shutdown.
/// </summary>
/// <param name="cancellationToken">Indicates that the shutdown process should no longer be graceful.</param>
public virtual async Task StopAsync(CancellationToken cancellationToken)
{
// Stop called without start
if (_executingTask == null)
{
return;
}
try
{
// Signal cancellation to the executing method
_stoppingCts.Cancel();
}
finally
{
// Wait until the task completes or the stop token triggers
await Task.WhenAny(_executingTask, Task.Delay(Timeout.Infinite, cancellationToken));
}
}
public virtual void Dispose()
{
_stoppingCts.Cancel();
}
}
- 另外我们需要创建一个HostedService.cs后台任务服务类型用于继承BackgroundService.cs抽象类,HostedService.cs代码如下:
public class HostedService : BackgroundService
{
private readonly IServiceProvider _services;
private readonly ILogger<HostedService> _logger;
private readonly IHostApplicationLifetime _hostApplicationLifetime;
public HostedService(
IHostApplicationLifetime hostApplicationLifetime,
ILogger<HostedService> logger,
IServiceProvider services)
{
_logger = logger;
_services = services;
_hostApplicationLifetime = hostApplicationLifetime;
_hostApplicationLifetime.ApplicationStarted.Register(OnApplicationStarted);
_hostApplicationLifetime.ApplicationStopping.Register(OnApplicationStopping);
_hostApplicationLifetime.ApplicationStopped.Register(OnApplicationStopped);
}
private void OnApplicationStopped()
{
}
private void OnApplicationStopping()
{
}
private void OnApplicationStarted()
{
}
public override void Dispose()
{
base.Dispose();
}
public override Task StartAsync(CancellationToken cancellationToken)
{
return base.StartAsync(cancellationToken);
}
public override Task StopAsync(CancellationToken cancellationToken)
{
_logger.LogWarning("服务停止……");
return base.StopAsync(cancellationToken);
}
protected override Task ExecuteAsync(CancellationToken stoppingToken)
{
_logger.LogInformation("服务启动……");
new Task(() =>
{
while (!stoppingToken.IsCancellationRequested)
{
// Do work here
Console.WriteLine("Doing work...");
Thread.Sleep(1000);
}
}, stoppingToken).Start();
_logger.LogInformation("服务启动成功!");
return Task.CompletedTask;
}
}
Program.cs中的配置如下:
namespace WebApplication26
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
/// <summary>
/// This method gets called by the runtime. Use this method to add services to the container.
/// </summary>
/// <param name="services"></param>
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddEndpointsApiExplorer();
services.AddSwaggerGen();
services.AddMvc(options =>
{
options.EnableEndpointRouting = false; //禁用控制器名称的小写化
//options.Filters.Add<RequestResultFilterAttribute>(); // 注册一个全局过滤器
options.InputFormatters.Clear(); // 使用自定义的 JSON 解析选项
//options.InputFormatters.Add(new CustomJsonInputFormatter());
//options.Conventions.Add(new CustomRouteConvention()); // 添加一个自定义的路由约定
});
services.AddMemoryCache(); //配置缓存
//注册定时任务执行类【https://blog.51cto.com/u_15437432/6172040?articleABtest=0】
//添加主机服务
services.AddHostedService<HostedService>(); //配置后台线程任务
}
/// <summary>
/// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
/// </summary>
/// <param name="app"></param>
/// <param name="env"></param>
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment()) //在开发环境中
{
app.UseDeveloperExceptionPage(); // 在开发环境中启用异常页面(可选)
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseSwagger(); // 启用Swagger中间件以生成和提供Swagger文档
app.UseSwaggerUI(c => // 启用Swagger UI中间件以提供Swagger文档的UI界面
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1.0"); // 指定Swagger文档的端点和名称
});
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}
主要是这段代码
services.AddHostedService<HostedService>();
参考网址【https://blog.51cto.com/u_15437432/6172040?articleABtest=0】