当前位置:首页 > 科技  > 软件

.NET 8 的 IHostedLifecycleService 接口是鸡肋功能吗?

来源: 责编: 时间:2024-01-03 09:12:19 288观看
导读.NET 8 引入了一个新的接口,叫做IHostedLifecycleService,这个接口继承自现有的 IHostedService 接口,它为 BackgroundService 提供了一些新的生命周期事件的方法:StartingAsync:在 StartAsync 方法之前执行,用于执行一些初

.NET 8 引入了一个新的接口,叫做IHostedLifecycleService,这个接口继承自现有的 IHostedService 接口,它为 BackgroundService 提供了一些新的生命周期事件的方法:AII28资讯网——每日最新资讯28at.com

  • StartingAsync:在 StartAsync 方法之前执行,用于执行一些初始化或预处理的逻辑。
  • StartedAsync:在 StartAsync 方法之后执行,用于执行一些后处理或检查的逻辑。
  • StoppingAsync:在 StopAsync 方法之前执行,用于执行一些清理或释放的逻辑。
  • StoppedAsync:在 StopAsync 方法之后执行,用于执行一些收尾或报告的逻辑。

这些方法都发生在现有的 StartAsync 和 StopAsync 方法之前或之后。AII28资讯网——每日最新资讯28at.com

示例代码

下面的示例演示如何使用新 API:AII28资讯网——每日最新资讯28at.com

var builder = Host.CreateApplicationBuilder(args);builder.Services.AddHostedService<MyIOWorker>();var host = builder.Build();host.Run();public class MyIOWorker : BackgroundService, IHostedLifecycleService{    public async Task StartingAsync(CancellationToken cancellationToken)    {        Console.WriteLine($"{nameof(MyIOWorker)} Starting");//业务逻辑    }    public async Task StartedAsync(CancellationToken cancellationToken)    {        Console.WriteLine($"{nameof(MyIOWorker)} Started");//业务逻辑    }    public async Task StoppingAsync(CancellationToken cancellationToken)    {        Console.WriteLine($"{nameof(MyIOWorker)} Stopping");//业务逻辑    }    public async Task StoppedAsync(CancellationToken cancellationToken)    {        Console.WriteLine($"{nameof(MyIOWorker)} Stopped");//业务逻辑    }    protected override async Task ExecuteAsync(CancellationToken stoppingToken)    {        while (!stoppingToken.IsCancellationRequested)        {            Console.WriteLine($"{nameof(MyIOWorker)} Execute");//业务逻辑            await Task.Delay(1000, stoppingToken);        }    }}

输出结果如下:AII28资讯网——每日最新资讯28at.com

MyIOService StartingMyIOService ExecuteMyIOService Started...MyIOService StoppingMyIOService Stopped

鸡肋功能?

但是,直接使用 IHostedService 接口一样可以实现相同功能:AII28资讯网——每日最新资讯28at.com

public class MyIOWorker : BackgroundService{     public override async Task StartAsync(CancellationToken cancellationToken)    {        Console.WriteLine($"{nameof(MyIOWorker)} Starting");//业务逻辑        await base.StartAsync(cancellationToken);        Console.WriteLine($"{nameof(MyIOWorker)} Started");//业务逻辑    }         public override async Task StopAsync(CancellationToken cancellationToken)    {        Console.WriteLine($"{nameof(MyIOWorker)} Stopping");//业务逻辑        await base.StopAsync(cancellationToken);        Console.WriteLine($"{nameof(MyIOWorker)} Stopped");//业务逻辑    }        protected override async Task ExecuteAsync(CancellationToken stoppingToken)    {        while (!stoppingToken.IsCancellationRequested)        {            Console.WriteLine($"{nameof(MyIOWorker)} ExecuteAsync");//业务逻辑            await Task.Delay(1000, stoppingToken);        }    }}

那么,新特性IHostedLifecycleService的意义何在呢?AII28资讯网——每日最新资讯28at.com

仅仅为了,方便放置不同逻辑的代码吗?AII28资讯网——每日最新资讯28at.com

探究源码

在dotnet/runtime源码https://github.com/dotnet/runtime/blob/main/src/libraries/Microsoft.Extensions.Hosting/src/Internal/Host.cs中,我们找到了 IHostedLifecycleService 的使用逻辑:AII28资讯网——每日最新资讯28at.com

// Call StartingAsync().if (_hostedLifecycleServices is not null){    await ForeachService(_hostedLifecycleServices, cancellationToken, concurrent, abortOnFirstException, exceptions,        (service, token) => service.StartingAsync(token)).ConfigureAwait(false);    // Exceptions in StartingAsync cause startup to be aborted.    LogAndRethrow();}// Call StartAsync().await ForeachService(_hostedServices, cancellationToken, concurrent, abortOnFirstException, exceptions,    async (service, token) =>    {        await service.StartAsync(token).ConfigureAwait(false);        if (service is BackgroundService backgroundService)        {            _ = TryExecuteBackgroundServiceAsync(backgroundService);        }    }).ConfigureAwait(false);// Exceptions in StartAsync cause startup to be aborted.LogAndRethrow();// Call StartedAsync().if (_hostedLifecycleServices is not null){    await ForeachService(_hostedLifecycleServices, cancellationToken, concurrent, abortOnFirstException, exceptions,        (service, token) => service.StartedAsync(token)).ConfigureAwait(false);}

上面的代码先遍历执行IEnumerable<IHostedLifecycleService>? _hostedLifecycleServices的StartingAsync方法,再遍历执行IEnumerable<IHostedService>? _hostedServices的StartAsync方法。AII28资讯网——每日最新资讯28at.com

也就是说,如果存在多个IHostedLifecycleService实现,我们可以把初始化代码放在StartingAsync方法实现中,保证了全部初始化逻辑执行成功后才会执行StartAsync方法中正式的业务逻辑。对于StopAsync方法也是同理。AII28资讯网——每日最新资讯28at.com

使用场景

比如,如果直接使用 IHostedService 接口:AII28资讯网——每日最新资讯28at.com

builder.Services.AddHostedService<AWorker>();builder.Services.AddHostedService<BWorker>();public class AWorker : BackgroundService{     public override async Task StartAsync(CancellationToken cancellationToken)    {        //初始化数据库A表    }     protected override async Task ExecuteAsync(CancellationToken stoppingToken)    {        //访问数据库A表和B表    }}public class BWorker : BackgroundService{     public override async Task StartAsync(CancellationToken cancellationToken)    {        //初始化数据库B表    }     protected override async Task ExecuteAsync(CancellationToken stoppingToken)    {        //访问数据库A表和B表    }}

由于执行有先后顺序,初始化数据库B表操作还没有执行,AWorker 就已经开始执行ExecuteAsync方法了,AWorker 的访问数据库A表和B表操作可能产生不可预料的结果。AII28资讯网——每日最新资讯28at.com

现在使用IHostedLifecycleService,将初始化放在生命周期的早期:AII28资讯网——每日最新资讯28at.com

public class AWorker : BackgroundService, IHostedLifecycleService{    public async Task StartingAsync(CancellationToken cancellationToken)    {        //初始化数据库A表    }     protected override async Task ExecuteAsync(CancellationToken stoppingToken)    {        //访问数据库A表和B表    }}public class BWorker : BackgroundService, IHostedLifecycleService{    public async Task StartingAsync(CancellationToken cancellationToken)    {        //初始化数据库B表    }     protected override async Task ExecuteAsync(CancellationToken stoppingToken)    {        //访问数据库A表和B表    }}

现在,访问数据库A表和B表操作可以保证正常执行了。AII28资讯网——每日最新资讯28at.com

默认情况下,多个IHostedLifecycleService实现是按顺序执行的,我们还可以设置它们并发启动和停止,节约整体启动时间:AII28资讯网——每日最新资讯28at.com

builder.Services.Configure<HostOptions>(options =>{    options.ServicesStartConcurrently = true;    options.ServicesStopConcurrently = true;});

总结

IHostedLifecycleService是.NET 8中引入的一个新特性,它可以让我们在使用多个IHostedService实现的时候,更加灵活和高效地控制它们的启动和停止,避免出现不必要的依赖和冲突。AII28资讯网——每日最新资讯28at.com

AII28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-56563-0.html.NET 8 的 IHostedLifecycleService 接口是鸡肋功能吗?

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: Pulsar3.0新功能,你了解了吗?

下一篇: 如何提高 Java 代码的可重用性

标签:
  • 热门焦点
  • MIX Fold3包装盒泄露 新机本月登场

    小米的全新折叠屏旗舰MIX Fold3将于本月发布,近日该机的真机包装盒在网上泄露。从图上来看,新的MIX Fold3包装盒在外观设计方面延续了之前的方案,变化不大,这也是目前小米旗舰
  • 一年经验在二线城市面试后端的经验分享

    忠告这篇文章只适合2年内工作经验、甚至没有工作经验的朋友阅读。如果你是2年以上工作经验,请果断划走,对你没啥帮助~主人公这篇文章内容来自 「升职加薪」星球星友 的投稿,坐
  • 三分钟白话RocketMQ系列—— 如何发送消息

    我们知道RocketMQ主要分为消息 生产、存储(消息堆积)、消费 三大块领域。那接下来,我们白话一下,RocketMQ是如何发送消息的,揭秘消息生产全过程。注意,如果白话中不小心提到相关代
  • 破圈是B站头上的紧箍咒

    来源 | 光子星球撰文 | 吴坤谚编辑 | 吴先之每年的暑期档都少不了瞄准追剧女孩们的古偶剧集,2021年有优酷的《山河令》,2022年有爱奇艺的《苍兰诀》,今年却轮到小破站抓住了追
  • 年轻人的“职场羞耻感”,无处不在

    作者:冯晓亭 陶 淘 李 欣 张 琳 马舒叶来源:燃次元&ldquo;人在职场,应该选择什么样的着装?&rdquo;近日,在网络上,一个与着装相关的帖子引发关注,在该帖子里,一位在高级写字楼亚洲金
  • 华为Mate 60保护壳曝光:硕大后置相机模组 凸起程度有惊喜

    这段时间以来,关于华为新旗舰的爆料日渐密集。据此前多方爆料,今年华为将开始恢复一年双旗舰战略,除上半年推出的P60系列外,往年下半年的Mate系列也将
  • iQOO Neo8 Pro抢先上架:首发天玑9200+ 安卓性能之王

    经过了一段时间的密集爆料,昨日iQOO官方如期对外宣布:将于5月23日推出全新的iQOO Neo8系列新品,官方称这是一款拥有旗舰级性能调校的作品。随着发布时
  • iQOO Neo8 Pro真机谍照曝光:天玑9200+和V1+旗舰双芯加持

    去年10月,iQOO推出了iQOO Neo7系列机型,不仅搭载了天玑9000+,而且是同价位唯一一款天玑9000+直屏旗舰,一经上市便受到了用户的广泛关注。在时隔半年后,
  • 英特尔Xe HPG游戏显卡:拥有512EU,单风扇版本

    据10 月 30 日外媒 TheVerge 消息报道,英特尔 Xe HPG Arc Alchemist 的正面实被曝光,不仅拥有 512 EU 版显卡,还拥有 128EU 的单风扇版本。另外,这款显卡 PCB
Top