如何在 BackgroundService 获取 ASP.NET Core 启动地址

Posted dotNET跨平台

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在 BackgroundService 获取 ASP.NET Core 启动地址相关的知识,希望对你有一定的参考价值。

前言

上次,我们介绍了《如何获取 ASP.NET Core 启动地址》。

但是,如果要在 BackgroundService 中获取启动地址可不那么容易,因为 BackgroundService 在 app 启动前就开始执行了:

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHostedService<DemoBackgroundService>();

var app = builder.Build();

app.MapGet("/", () => "Hello My IO!");

await app.StartAsync();

Console.WriteLine(app.Urls.First());

await app.WaitForShutdownAsync();

internal class DemoBackgroundService : BackgroundService

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    
        Console.WriteLine("BackgroundService ExecuteAsync");
        await Task.CompletedTask;
    

那要怎么实现呢?

IHostApplicationLifetime

我们可以利用ASP.NET Core应用程序生存期事件,等待启动完成再获取启动地址:

internal class DemoBackgroundService : BackgroundService

    private readonly IServiceProvider _services;
    private string _url;

    public DemoBackgroundService(IServiceProvider services, IHostApplicationLifetime lifetime)
    
        _services = services;
        lifetime.ApplicationStarted.Register(OnAppStarted);
    
    public void OnAppStarted()
    
        var server = _services.GetService<IServer>();
        _url = server.Features.Get<IServerAddressesFeature>().Addresses.First();
    
    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    
        while (string.IsNullOrWhiteSpace(_url))
        
            await Task.Delay(1000); 
        
        
        Console.WriteLine("BackgroundService ExecuteAsync");
        Console.WriteLine(_url);

        await Task.CompletedTask;
    

现在可以正常获取 ASP.NET Core 启动地址了:

SemaphoreSlim

轮询虽然可以解决问题,但感觉不太优雅。

我们可以创建一个信号灯 SemaphoreSlim,在ExecuteAsync方法中等待信号灯,而在启动后释放信号灯:

static SemaphoreSlim semaphoreSlim = new SemaphoreSlim(0, 1);

public void OnAppStarted()

    ...
    semaphoreSlim.Release();

protected override async Task ExecuteAsync(CancellationToken stoppingToken)

    await semaphoreSlim.WaitAsync();
    ...

可以看到,这样还带来了另外一个好处,比上面的解决方式更快地进入到了 BackgroundService:

结论

今天,我们利用了ASP.NET Core应用程序生存期事件,实现了在 BackgroundService 获取 ASP.NET Core 启动地址。

添加微信号【MyIO666】,邀你加入技术交流群

以上是关于如何在 BackgroundService 获取 ASP.NET Core 启动地址的主要内容,如果未能解决你的问题,请参考以下文章

如何在 ASP.NET Core 2.1 中的计时器上运行 BackgroundService

从 BackgroundService 创建 DbContext 租户时配置它

从asp.net core 2.1中的控制器访问BackgroundService

android localytics 4.5.1 崩溃 NoClassDefFoundError com.localytics.android.BackgroundService

.NET Worker Service 如何优雅退出

使用 ASP.NET Core 6 Minimal API 在 Azure 中停止 Web 应用程序时未调用 BackgroundService StopAsync