日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢(xún)
選擇下列產(chǎn)品馬上在線(xiàn)溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
.NET8的IHostedLifecycleService接口是雞肋功能嗎?

.NET 8 引入了一個(gè)新的接口,叫做IHostedLifecycleService,這個(gè)接口繼承自現(xiàn)有的 IHostedService 接口,它為 BackgroundService 提供了一些新的生命周期事件的方法:

  • StartingAsync:在 StartAsync 方法之前執(zhí)行,用于執(zhí)行一些初始化或預(yù)處理的邏輯。
  • StartedAsync:在 StartAsync 方法之后執(zhí)行,用于執(zhí)行一些后處理或檢查的邏輯。
  • StoppingAsync:在 StopAsync 方法之前執(zhí)行,用于執(zhí)行一些清理或釋放的邏輯。
  • StoppedAsync:在 StopAsync 方法之后執(zhí)行,用于執(zhí)行一些收尾或報(bào)告的邏輯。

這些方法都發(fā)生在現(xiàn)有的 StartAsync 和 StopAsync 方法之前或之后。

示例代碼

下面的示例演示如何使用新 API:

var builder = Host.CreateApplicationBuilder(args);
builder.Services.AddHostedService();

var host = builder.Build();
host.Run();

public class MyIOWorker : BackgroundService, IHostedLifecycleService
{
    public async Task StartingAsync(CancellationToken cancellationToken)
    {
        Console.WriteLine($"{nameof(MyIOWorker)} Starting");//業(yè)務(wù)邏輯
    }
    public async Task StartedAsync(CancellationToken cancellationToken)
    {
        Console.WriteLine($"{nameof(MyIOWorker)} Started");//業(yè)務(wù)邏輯
    }
    public async Task StoppingAsync(CancellationToken cancellationToken)
    {
        Console.WriteLine($"{nameof(MyIOWorker)} Stopping");//業(yè)務(wù)邏輯
    }
    public async Task StoppedAsync(CancellationToken cancellationToken)
    {
        Console.WriteLine($"{nameof(MyIOWorker)} Stopped");//業(yè)務(wù)邏輯
    }
    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            Console.WriteLine($"{nameof(MyIOWorker)} Execute");//業(yè)務(wù)邏輯
            await Task.Delay(1000, stoppingToken);
        }
    }
}

輸出結(jié)果如下:

MyIOService Starting
MyIOService Execute
MyIOService Started

...

MyIOService Stopping
MyIOService Stopped

雞肋功能?

但是,直接使用 IHostedService 接口一樣可以實(shí)現(xiàn)相同功能:

public class MyIOWorker : BackgroundService
{ 
    public override async Task StartAsync(CancellationToken cancellationToken)
    {
        Console.WriteLine($"{nameof(MyIOWorker)} Starting");//業(yè)務(wù)邏輯
        await base.StartAsync(cancellationToken);
        Console.WriteLine($"{nameof(MyIOWorker)} Started");//業(yè)務(wù)邏輯
    }
     
    public override async Task StopAsync(CancellationToken cancellationToken)
    {
        Console.WriteLine($"{nameof(MyIOWorker)} Stopping");//業(yè)務(wù)邏輯
        await base.StopAsync(cancellationToken);
        Console.WriteLine($"{nameof(MyIOWorker)} Stopped");//業(yè)務(wù)邏輯
    }
    
    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            Console.WriteLine($"{nameof(MyIOWorker)} ExecuteAsync");//業(yè)務(wù)邏輯
            await Task.Delay(1000, stoppingToken);
        }
    }
}

那么,新特性IHostedLifecycleService的意義何在呢?

僅僅為了,方便放置不同邏輯的代碼嗎?

探究源碼

在dotnet/runtime源碼https://github.com/dotnet/runtime/blob/main/src/libraries/Microsoft.Extensions.Hosting/src/Internal/Host.cs中,我們找到了 IHostedLifecycleService 的使用邏輯:

// 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);
}

上面的代碼先遍歷執(zhí)行IEnumerable? _hostedLifecycleServices的StartingAsync方法,再遍歷執(zhí)行IEnumerable? _hostedServices的StartAsync方法。

也就是說(shuō),如果存在多個(gè)IHostedLifecycleService實(shí)現(xiàn),我們可以把初始化代碼放在StartingAsync方法實(shí)現(xiàn)中,保證了全部初始化邏輯執(zhí)行成功后才會(huì)執(zhí)行StartAsync方法中正式的業(yè)務(wù)邏輯。對(duì)于StopAsync方法也是同理。

使用場(chǎng)景

比如,如果直接使用 IHostedService 接口:

builder.Services.AddHostedService();
builder.Services.AddHostedService();

public class AWorker : BackgroundService
{ 
    public override async Task StartAsync(CancellationToken cancellationToken)
    {
        //初始化數(shù)據(jù)庫(kù)A表
    } 
    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        //訪(fǎng)問(wèn)數(shù)據(jù)庫(kù)A表和B表
    }
}

public class BWorker : BackgroundService
{ 
    public override async Task StartAsync(CancellationToken cancellationToken)
    {
        //初始化數(shù)據(jù)庫(kù)B表
    } 
    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        //訪(fǎng)問(wèn)數(shù)據(jù)庫(kù)A表和B表
    }
}

由于執(zhí)行有先后順序,初始化數(shù)據(jù)庫(kù)B表操作還沒(méi)有執(zhí)行,AWorker 就已經(jīng)開(kāi)始執(zhí)行ExecuteAsync方法了,AWorker 的訪(fǎng)問(wèn)數(shù)據(jù)庫(kù)A表和B表操作可能產(chǎn)生不可預(yù)料的結(jié)果。

現(xiàn)在使用IHostedLifecycleService,將初始化放在生命周期的早期:

public class AWorker : BackgroundService, IHostedLifecycleService
{
    public async Task StartingAsync(CancellationToken cancellationToken)
    {
        //初始化數(shù)據(jù)庫(kù)A表
    } 
    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        //訪(fǎng)問(wèn)數(shù)據(jù)庫(kù)A表和B表
    }
}

public class BWorker : BackgroundService, IHostedLifecycleService
{
    public async Task StartingAsync(CancellationToken cancellationToken)
    {
        //初始化數(shù)據(jù)庫(kù)B表
    } 
    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        //訪(fǎng)問(wèn)數(shù)據(jù)庫(kù)A表和B表
    }
}

現(xiàn)在,訪(fǎng)問(wèn)數(shù)據(jù)庫(kù)A表和B表操作可以保證正常執(zhí)行了。

默認(rèn)情況下,多個(gè)IHostedLifecycleService實(shí)現(xiàn)是按順序執(zhí)行的,我們還可以設(shè)置它們并發(fā)啟動(dòng)和停止,節(jié)約整體啟動(dòng)時(shí)間:

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

總結(jié)

IHostedLifecycleService是.NET 8中引入的一個(gè)新特性,它可以讓我們?cè)谑褂枚鄠€(gè)IHostedService實(shí)現(xiàn)的時(shí)候,更加靈活和高效地控制它們的啟動(dòng)和停止,避免出現(xiàn)不必要的依賴(lài)和沖突。


分享文章:.NET8的IHostedLifecycleService接口是雞肋功能嗎?
本文網(wǎng)址:http://www.dlmjj.cn/article/dpicjeg.html