首页 > 其他分享 >BackgroundService and IHostedService

BackgroundService and IHostedService

时间:2024-08-05 16:52:20浏览次数:15  
标签:Task BackgroundService StopAsync LogInformation MyBackgroundService logger IHost

IHostedService:

适用于需要更高灵活性和控制的场景。
需要自定义启动和停止逻辑。
适用于复杂的后台任务管理。
BackgroundService:

适用于需要简单实现后台任务的场景。
提供了一个方便的抽象,减少样板代码。
适用于大多数常见的后台任务。

public class MyHostedService : IHostedService
{
    private readonly ILogger<MyHostedService> _logger;
    private Timer _timer;

    public MyHostedService(ILogger<MyHostedService> logger)
    {
        _logger = logger;
    }

    public Task StartAsync(CancellationToken cancellationToken)
    {
        _logger.LogInformation("MyHostedService is starting.");
        _timer = new Timer(DoWork, null, TimeSpan.Zero, TimeSpan.FromSeconds(5));
        return Task.CompletedTask;
    }

    private void DoWork(object state)
    {
        _logger.LogInformation("MyHostedService is working.");
    }

    public Task StopAsync(CancellationToken cancellationToken)
    {
        _logger.LogInformation("MyHostedService is stopping.");
        _timer?.Change(Timeout.Infinite, 0);
        return Task.CompletedTask;
    }

    public void Dispose()
    {
        _timer?.Dispose();
    }
}

在 BackgroundService 中,StopAsync 是用来优雅地停止服务的。当应用程序停止时,StopAsync 会被调用,并且 CancellationToken 会被触发,这将会请求 ExecuteAsync 停止运行。然而,StopAsync 并不会等待 ExecuteAsync 自行完成;相反,StopAsync 会立即开始执行。

为了确保 ExecuteAsync 完成后再执行 StopAsync 中的逻辑,可以在 ExecuteAsync 内部检测到取消请求时进行清理,然后将 ExecuteAsync 任务与 StopAsync 协调起来。

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
using System.Threading;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        var host = Host.CreateDefaultBuilder(args)
            .ConfigureServices((hostContext, services) =>
            {
                services.AddHostedService<MyBackgroundService>();
            })
            .Build();

        await host.RunAsync();
    }
}

public class MyBackgroundService : BackgroundService
{
    private readonly ILogger<MyBackgroundService> _logger;
    private Task _executingTask;
    private readonly IHostApplicationLifetime _applicationLifetime;
    private CancellationTokenSource _stoppingCts = new CancellationTokenSource();

    public MyBackgroundService(ILogger<MyBackgroundService> logger, IHostApplicationLifetime applicationLifetime)
    {
        _logger = logger;
        _applicationLifetime = applicationLifetime;
    }

    protected override Task ExecuteAsync(CancellationToken stoppingToken)
    {
        _logger.LogInformation("MyBackgroundService is starting.");

        stoppingToken.Register(() => _logger.LogInformation("MyBackgroundService is stopping."));

        _executingTask = Task.Run(async () =>
        {
            while (!stoppingToken.IsCancellationRequested)
            {
                _logger.LogInformation("MyBackgroundService is running.");
                await Task.Delay(5000, stoppingToken);
            }

            _logger.LogInformation("MyBackgroundService is completing background work.");
            // 在这里添加任何清理逻辑,例如关闭资源等

            _logger.LogInformation("MyBackgroundService has stopped.");
        }, stoppingToken);

        return _executingTask;
    }

    public override async Task StopAsync(CancellationToken cancellationToken)
    {
        _logger.LogInformation("MyBackgroundService is executing StopAsync.");

        // 请求停止
        if (_executingTask == null)
        {
            return;
        }

        try
        {
            _stoppingCts.Cancel();
        }
        finally
        {
            // 等待任务完成
            await Task.WhenAny(_executingTask, Task.Delay(Timeout.Infinite, cancellationToken));
        }
        
        _logger.LogInformation("MyBackgroundService has completed StopAsync.");
    }
    
    public override void Dispose()
    {
        _stoppingCts.Cancel();
        base.Dispose();
    }

    public async Task StopServiceAsync()
    {
        _logger.LogInformation("Stopping the service internally...");
        _applicationLifetime.StopApplication();
    }
}

参考:
BackgroundService Graceful Shutdown - Complete work and write to DB
https://stackoverflow.com/questions/70036809/backgroundservice-graceful-shutdown-complete-work-and-write-to-db

标签:Task,BackgroundService,StopAsync,LogInformation,MyBackgroundService,logger,IHost
From: https://www.cnblogs.com/JosenEarth/p/18343566

相关文章

  • dot net core使用BackgroundService运行一个后台服务
    不管是在控制台程序还是asp.netcore程序中,我们经常会有用到一个需要长时间运行的后台任务的需求。通常最直觉的方式是使用Thread实例来新建一个线程,但是这样需要自行管理线程的启动和停止。在.netcore中提供了一个继承自IHostedService的基类BackgroudService能够方便地实现一......
  • Blazor里,如何在 razor 页面使用 BackgroundService 实例
    Blazor使用BackgroundService需要注册builder.Services.AddHostedService<PageStateService>();razor页面要使用 PageStateService的实例,需要 PageStateService有接口,我们给PageStateService写一个接口 IPageStateService然后在页面直接注入实例@injectIPageSt......
  • .net实现后台服务就这么简单,只要实现IHostedService接口就行了
     IHostedService 接口在.NETCore中的主要用途是定义应用程序生命周期内运行的后台服务。这些服务可以执行初始化、长时间运行的任务、定期运行的任务等。通过实例,我们可以演示如何使用 IHostedService 来实现一个简单的网络检测服务,并记录日志。首先,我们需要创建一个实现......
  • 托管服务简介IHostedService接口 继承 BackgroundSerice接口
    1.场景:代码运行在后台,比如服务器启动的时候在后台预先加载数据到缓存,每天凌晨3点把数据到处到数据库备份,每隔5秒在两张表之间同步一次数据;2.托管服务实现IHoutedService接口,一般编写从BackgroundService继承的类;测试:延迟若干秒读取文件,在延迟,在输出;3.service.AddHostedServ......
  • net core-调用接口方式实现IHostedService的停止和启动
    usingMicrosoft.AspNetCore.Mvc;usingMicrosoft.AspNetCore.Authorization;[Route("home")][AllowAnonymous]publicclassHomeController:ControllerBase{ privatereadonlyIEnumerable<IHostedService>_hostedServices; privatereadonlyRec......
  • net core中BackgroundService
    publicclassPeriodicBackgroundTask:BackgroundService{privatereadonlyTimeSpan_period=TimeSpan.FromSeconds(5);privatereadonlyILogger<PeriodicBackgroundTask>_logger;publicPeriodicBackgroundTask(ILogger<PeriodicBackgroundT......
  • android.app.BackgroundServiceStartNotAllowedException
    ---------beginningofcrash05-0901:25:24.46521872187EAndroidRuntime:FATALEXCEPTION:main05-0901:25:24.46521872187EAndroidRuntime:Process:com.android.gallery3d,PID:218705-0901:25:24.46521872187EAndroidRuntime:java.lang.Runti......
  • PeriodicTimer 和 BackgroundService
    实现.Net7下的数据库定时检查 在软件开发过程中,有时候我们需要定时地检查数据库中的数据,并在发现新增数据时触发一个动作。为了实现这个需求,我们在.Net7下进行一次简单的演示。PeriodicTimer.Net6中新增了PeriodicTimer这个类,它可以用来创建一个定时器,以固定间隔......
  • .NET Core 实现后台任务(定时任务)IHostedService
    program添加服务//.Net6builder.Services.AddHostedService<TestHostedService>();//.Net5及以下services.AddHostedService<TestHostedService>(); 添......
  • ASP.NET Core 的 BackgroundService
    说明托管服务的使用非常简单,只要编写一个实现了IHostedService接口的类即可。一般情况下我们编写从BackgroundService类继承的类,因为BackgroundService实现了IHostedServ......