.Net Core注册一个定制任务执行类服务

发布于:2024-12-19 ⋅ 阅读:(15) ⋅ 点赞:(0)

如果我们想要在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】