欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

.NET 8 強(qiáng)大功能 IHostedService 與 BackgroundService 實(shí)戰(zhàn)教程

 更新時(shí)間:2024年11月18日 09:55:20   作者:小碼編匠  
.NET 8 中的 IHostedService 和 BackgroundService 提供了強(qiáng)大的工具集,使定時(shí)任務(wù)、后臺(tái)處理以及定期維護(hù)等功能的實(shí)現(xiàn)變得更加直接、高效和靈活,感興趣的朋友跟隨小編一起看看吧

前言

在.NET 8中,IHostedService 和 BackgroundService 兩個(gè)核心接口的引入,增強(qiáng)了項(xiàng)目開(kāi)發(fā)中處理定時(shí)任務(wù)的能力。這兩個(gè)接口不僅簡(jiǎn)化了定時(shí)任務(wù)、后臺(tái)處理作業(yè)以及定期維護(hù)任務(wù)的實(shí)現(xiàn)過(guò)程,還提升了在ASP.NET Core 或任何基于.NET的宿主應(yīng)用程序中的集成與管理效率。

IHostedService接口提供了一個(gè)基本的框架,允許自定義后臺(tái)服務(wù)的啟動(dòng)和停止邏輯。通過(guò)實(shí)現(xiàn)該接口,可以靈活地控制服務(wù)的生命周期,確保任務(wù)在應(yīng)用程序啟動(dòng)時(shí)自動(dòng)運(yùn)行,并在應(yīng)用程序關(guān)閉時(shí)結(jié)束。

而 BackgroundService 類則是對(duì) IHostedService 接口的進(jìn)一步封裝,它專為需要長(zhǎng)時(shí)間運(yùn)行的任務(wù)而設(shè)計(jì)。

通過(guò)繼承 BackgroundService并重寫(xiě)其 ExecuteAsync方法,可以輕松地實(shí)現(xiàn)復(fù)雜的后臺(tái)邏輯,如循環(huán)執(zhí)行的任務(wù)、基于時(shí)間間隔的操作等。這種設(shè)計(jì)模式讓代碼的可讀性和可維護(hù)性變的更好。

利用這些功能,可以快速構(gòu)建出高效、可靠的定時(shí)任務(wù)系統(tǒng),用于執(zhí)行諸如消息推送、數(shù)據(jù)更新、定時(shí)發(fā)布等關(guān)鍵業(yè)務(wù)操作。這些任務(wù)可以在不影響應(yīng)用程序主流程的情況下獨(dú)立運(yùn)行,從而提高了整個(gè)系統(tǒng)的性能和穩(wěn)定性。

介紹

.NET 中的后臺(tái)服務(wù)允許在后臺(tái)獨(dú)立于主應(yīng)用程序線程運(yùn)行任務(wù)。這對(duì)于需要連續(xù)或定期運(yùn)行而不阻塞主應(yīng)用程序流的任務(wù)至關(guān)重要。

IHostedService

IHostedService 是一個(gè)簡(jiǎn)單的接口,用于實(shí)現(xiàn)后臺(tái)服務(wù)。當(dāng)需要實(shí)現(xiàn)自定義的托管服務(wù)時(shí),可以通過(guò)實(shí)現(xiàn)這個(gè)接口來(lái)創(chuàng)建。

該接口定義了兩個(gè)方法:StartAsync(CancellationToken cancellationToken) 和 StopAsync(CancellationToken cancellationToken),分別用于啟動(dòng)和停止服務(wù)。

BackgroundService

BackgroundService 是一個(gè)抽象類,它繼承自 IHostedService 并提供了更簡(jiǎn)潔的方式來(lái)編寫(xiě)后臺(tái)服務(wù)。它通常用于需要長(zhǎng)時(shí)間運(yùn)行的任務(wù),如監(jiān)聽(tīng)器、工作隊(duì)列處理器等。通過(guò)重寫(xiě) ExecuteAsync(CancellationToken stoppingToken)方法,可以在其中編寫(xiě)任務(wù)的邏輯。ExecuteAsync方法會(huì)循環(huán)在后臺(tái)執(zhí)行,直到服務(wù)停止。

IHostedService 示例

1、注冊(cè)服務(wù)

Program.cs 中添加配置,.NET 5 及以下在需要在 Startup.cs 注冊(cè)服務(wù)。

// .NET 8
using ManageCore.Api;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddHostedService<DemoHostedService>();
var app = builder.Build();

2、創(chuàng)建服務(wù)接口

創(chuàng)建一個(gè)類,該類繼承 IHostedService 接口,并實(shí)現(xiàn)該接口成員.

在不需要定時(shí)執(zhí)行任務(wù)的時(shí)候,也可以在這里進(jìn)行應(yīng)用啟動(dòng)后的操作,例如創(chuàng)建 RabbitMQ 連接

using Microsoft.Extensions.Hosting;
namespace ManageCore.Api
{
    public class DemoHostedService : IHostedService, IDisposable
    {
        private Timer? _timer;
        public Task StartAsync(CancellationToken cancellationToken)
        {
            _timer = new Timer(DoWork, null, TimeSpan.Zero, TimeSpan.FromSeconds(5));
            return Task.CompletedTask;
        }
        private void DoWork(object? state)
        {
            Console.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss}");
        }
        public Task StopAsync(CancellationToken cancellationToken)
        {
            Console.WriteLine("StopAsync");
            return Task.CompletedTask;
        }
        public void Dispose()
        {
            _timer?.Dispose();
        }
    }
}

上面的Demo代碼非常簡(jiǎn)單,應(yīng)用在運(yùn)行后,會(huì)去執(zhí)行 StartAsync 函數(shù),應(yīng)用關(guān)閉執(zhí)行 StopAsync,由于這里使用的定時(shí)器,所以每過(guò)5秒都會(huì)執(zhí)行一次 DoWork 函數(shù)。

 3、運(yùn)行效果

4、IHostedService 說(shuō)明

注意:定時(shí)是不等待任務(wù)執(zhí)行完成,只要時(shí)間一到,就會(huì)調(diào)用 DoWork 函數(shù),所以適合一些簡(jiǎn)單、特定的場(chǎng)景。

以下為官方文檔對(duì) IHostedService 接口 的說(shuō)明

IHostedService 接口為主機(jī)托管的對(duì)象定義了兩種方法:

  • StartAsync(CancellationToken)
  • StopAsync(CancellationToken)

StartAsync(CancellationToken) 包含用于啟動(dòng)后臺(tái)任務(wù)的邏輯。 在以下操作之前調(diào)用 `StartAsync`:已配置應(yīng)用的請(qǐng)求處理管道。已啟動(dòng)服務(wù)器且已觸發(fā) IApplicationLifetime.ApplicationStarted。

StartAsync應(yīng)僅限于短期任務(wù),因?yàn)橥泄芊?wù)是按順序運(yùn)行的,在 StartAsync 運(yùn)行完成之前不會(huì)啟動(dòng)其他服務(wù)。

StopAsync(CancellationToken) 在主機(jī)執(zhí)行正常關(guān)閉時(shí)觸發(fā)。 StopAsync`包含結(jié)束后臺(tái)任務(wù)的邏輯。 實(shí)現(xiàn) IDisposable 和終結(jié)器(析構(gòu)函數(shù))以處置任何非托管資源。

默認(rèn)情況下,取消令牌會(huì)有五秒超時(shí),以指示關(guān)閉進(jìn)程不再正常。 在令牌上請(qǐng)求取消時(shí):

  • 應(yīng)中止應(yīng)用正在執(zhí)行的任何剩余后臺(tái)操作。
  • StopAsync 中調(diào)用的任何方法都應(yīng)及時(shí)返回。

但是,在請(qǐng)求取消后,將不會(huì)放棄任務(wù),調(diào)用方會(huì)等待所有任務(wù)完成。

如果應(yīng)用意外關(guān)閉(例如,應(yīng)用的進(jìn)程失?。?,則可能不會(huì)調(diào)用 StopAsync。 因此,在 StopAsync 中執(zhí)行的任何方法或操作都可能不會(huì)發(fā)生。

若要延長(zhǎng)默認(rèn)值為 5 秒的關(guān)閉超時(shí)值,請(qǐng)?jiān)O(shè)置:

  • ShutdownTimeout(當(dāng)使用通用主機(jī)時(shí))
  • 使用 Web 主機(jī)時(shí)為關(guān)閉超時(shí)值主機(jī)配置設(shè)置

托管服務(wù)在應(yīng)用啟動(dòng)時(shí)激活一次,在應(yīng)用關(guān)閉時(shí)正常關(guān)閉。 如果在執(zhí)行后臺(tái)任務(wù)期間引發(fā)錯(cuò)誤,即使未調(diào)用 StopAsync,也應(yīng)調(diào)用 Dispose。

BackgroundService 示例

1、注冊(cè)服務(wù)

首先,同樣需要在配置中注冊(cè)服務(wù)接口。

using ManageCore.Api;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddScoped<IDemoTaskWorkService, DemoTaskWorkService>();

 2、BackgroundService 源碼

查看 BackgroundService 的源碼,幫助我們理解BackgroundService 實(shí)現(xiàn)原理。BackgroundService 是 IHostedService的一個(gè)簡(jiǎn)單實(shí)現(xiàn),內(nèi)部 IHostedService 的 StartAsync 調(diào)用了 ExecuteAsync,本質(zhì)上就是使用了 IHostedService。

public abstract class BackgroundService : IHostedService, IDisposable
{
    private Task _executingTask;
    private readonly CancellationTokenSource _stoppingCts = new CancellationTokenSource();
    /// <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();
    }
}

3、創(chuàng)建服務(wù)接口

創(chuàng)建一個(gè)服務(wù)接口,定義需要實(shí)現(xiàn)的任務(wù),以及對(duì)應(yīng)的實(shí)現(xiàn),如果需要執(zhí)行異步方法,記得加上 await,不然任務(wù)將不會(huì)等待執(zhí)行結(jié)果,直接進(jìn)行下一個(gè)任務(wù)。

namespace ManageCore.Api
{
    public interface IDemoTaskWorkService
    {
        /// <summary>
        /// 測(cè)試任務(wù)
        /// </summary>
        /// <param name="stoppingToken"></param>
        /// <returns></returns>
        Task TaskWorkAsync(CancellationToken stoppingToken);
    }
}
public class DemoTaskWorkService : IDemoTaskWorkService
{
      /// <summary>
      /// 任務(wù)執(zhí)行
      /// </summary>
      /// <param name="stoppingToken"></param>
      /// <returns></returns>
      public async Task TaskWorkAsync(CancellationToken stoppingToken)
      {
          while (!stoppingToken.IsCancellationRequested)
          {
              //執(zhí)行任務(wù)
              Console.WriteLine($"{DateTime.Now}");
              //周期性任務(wù),于上次任務(wù)執(zhí)行完成后,等待5秒,執(zhí)行下一次任務(wù)
              await Task.Delay(500);
          }
      }
 }

創(chuàng)建后臺(tái)服務(wù)類,繼承基類 BackgroundService,這里需要注意的是,要在 BackgroundService 中使用有作用域的服務(wù),請(qǐng)創(chuàng)建作用域, 默認(rèn)情況下,不會(huì)為托管服務(wù)創(chuàng)建作用域,得自己管理服務(wù)的生命周期,切記!于構(gòu)造函數(shù)中注入 IServiceProvider即可。

namespace ManageCore.Api
{
    public class DemoBackgroundService : BackgroundService
    {
        private readonly IServiceProvider _services;
        public DemoBackgroundService(IServiceProvider services)
        {
            _services = services;
        }
        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            using var scope = _services.CreateScope();
            var taskWorkService = scope.ServiceProvider.GetRequiredService<IDemoTaskWorkService>();
            await taskWorkService.TaskWorkAsync(stoppingToken);
        }
    }
}

DemoBackgroundService類也是需要注冊(cè)的,注冊(cè)方式與 IHostedService 接口的方式一樣

builder.Services.AddHostedService<DemoBackgroundService>();

4、運(yùn)行效果

5、BackgroundService 說(shuō)明

BackgroundService 是用于實(shí)現(xiàn)長(zhǎng)時(shí)間運(yùn)行的 IHostedService 的基類。

調(diào)用 ExecuteAsync(CancellationToken) 來(lái)運(yùn)行后臺(tái)服務(wù)。 實(shí)現(xiàn)返回一個(gè) Task,其表示后臺(tái)服務(wù)的整個(gè)生存期。

在 ExecuteAsync 變?yōu)楫惒剑ɡ缤ㄟ^(guò)調(diào)用 await)之前,不會(huì)啟動(dòng)任何其他服務(wù)。 避免在 ExecuteAsync 中執(zhí)行長(zhǎng)時(shí)間的阻塞初始化工作。

StopAsync(CancellationToken) 中的主機(jī)塊等待完成 ExecuteAsync。

調(diào)用 IHostedService.StopAsync 時(shí),將觸發(fā)取消令牌。 當(dāng)激發(fā)取消令牌以便正常關(guān)閉服務(wù)時(shí),ExecuteAsync 的實(shí)現(xiàn)應(yīng)立即完成。 否則,服務(wù)將在關(guān)閉超時(shí)后不正常關(guān)閉。

StartAsync 應(yīng)僅限于短期任務(wù),因?yàn)橥泄芊?wù)是按順序運(yùn)行的,在 StartAsync 運(yùn)行完成之前不會(huì)啟動(dòng)其他服務(wù)。

長(zhǎng)期任務(wù)應(yīng)放置在 ExecuteAsync 中。

IHostedService 和 BackgroundService 區(qū)別

抽象級(jí)別

  • IHostedService:需要手動(dòng)實(shí)現(xiàn)啟動(dòng)和停止邏輯。
  • BackgroundService:通過(guò)提供具有要重寫(xiě)的單個(gè)方法的基類來(lái)簡(jiǎn)化實(shí)現(xiàn)。

使用案例

  • IHostedService:適用于需要對(duì)服務(wù)生命周期進(jìn)行精細(xì)控制的更復(fù)雜的方案。
  • BackgroundService:非常適合受益于減少樣板代碼的更簡(jiǎn)單、長(zhǎng)時(shí)間運(yùn)行的任務(wù)。

總結(jié)

總之.NET 8 中的 IHostedService 和 BackgroundService 提供了強(qiáng)大的工具集,使定時(shí)任務(wù)、后臺(tái)處理以及定期維護(hù)等功能的實(shí)現(xiàn)變得更加直接、高效和靈活。無(wú)論是構(gòu)建復(fù)雜的企業(yè)級(jí)應(yīng)用還是簡(jiǎn)單的服務(wù)應(yīng)用,這兩個(gè)組件都能提供穩(wěn)定且高效的解決方案。

到此這篇關(guān)于.NET 8 強(qiáng)大功能 IHostedService 與 BackgroundService 實(shí)戰(zhàn)的文章就介紹到這了,更多相關(guān).NET 8 IHostedService 與 BackgroundService 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • ASP.NET Core全局異常處理

    ASP.NET Core全局異常處理

    這篇文章介紹了ASP.NET Core全局異常處理的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-03-03
  • 詳解.NET主流的幾款重量級(jí)?ORM框架

    詳解.NET主流的幾款重量級(jí)?ORM框架

    這篇文章主要介紹了.NET主流的幾款重量級(jí)?ORM框架,市場(chǎng)上輕量級(jí)ORM有很多,比如Dapper、Chloe 本篇文章就介紹一下 功能比較多并且全的ORM,需要的朋友可以參考下
    2022-07-07
  • .NET Core 2.0遷移小技巧之web.config 配置文件示例詳解

    .NET Core 2.0遷移小技巧之web.config 配置文件示例詳解

    這篇文章主要給大家介紹了關(guān)于.NET Core 2.0遷移技巧之web.config 配置文件的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面跟著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-08-08
  • ASP.NET MVC學(xué)習(xí)教程之Razor語(yǔ)法

    ASP.NET MVC學(xué)習(xí)教程之Razor語(yǔ)法

    這篇文章主要給大家介紹了關(guān)于ASP.NET MVC學(xué)習(xí)教程之Razor語(yǔ)法的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2018-05-05
  • asp.net 文章內(nèi)容分頁(yè)顯示的代碼

    asp.net 文章內(nèi)容分頁(yè)顯示的代碼

    有種文章分頁(yè)的思路是用截取文本字符數(shù)的方法來(lái)處理,這個(gè)方法當(dāng)文章內(nèi)容是html代碼的話,分頁(yè)后會(huì)引起排版問(wèn)題。
    2009-01-01
  • 將文本文件的內(nèi)容或者文字保存成圖片的方法分享

    將文本文件的內(nèi)容或者文字保存成圖片的方法分享

    這篇文章主要介紹了將文本文件的內(nèi)容或者文字保存成圖片的方法,需要的朋友可以參考下
    2014-02-02
  • ASP.NET(C#) Web Api通過(guò)文件流下載文件的實(shí)例

    ASP.NET(C#) Web Api通過(guò)文件流下載文件的實(shí)例

    這篇文章主要介紹了ASP.NET(C#) Web Api通過(guò)文件流下載文件的方法,提供源碼下載,需要的朋友可以參考下。
    2016-06-06
  • DotNetCore深入了解之HttpClientFactory類詳解

    DotNetCore深入了解之HttpClientFactory類詳解

    這篇文章主要給大家介紹了關(guān)于DotNetCore深入了解之HttpClientFactory類的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • ASP.NET中事件如何依次發(fā)生?

    ASP.NET中事件如何依次發(fā)生?

    這篇文章主要介紹了ASP.NET中事件是如何依次發(fā)生的,
    2015-09-09
  • 解析.Net 4.0 中委托delegate的使用詳解

    解析.Net 4.0 中委托delegate的使用詳解

    本篇文章是對(duì).Net 4.0 中委托delegate的使用進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05

最新評(píng)論