您现在的位置是:首页 >技术杂谈 >.Net托管服务网站首页技术杂谈

.Net托管服务

风的艺术 2023-06-09 04:00:02
简介.Net托管服务

描述及使用场景

1、场景,代码运行在后台。比如服务器启动的时候在后台预先加载数据到缓存,每天凌晨3点把数据导出到备份数据库,每隔5秒钟在两张表之间同步一次数据。

2、托管服务实现IHostedService接口,一般编写从BackgroundService继承的类。

测试:延迟若干秒再读取文件,再延迟,再输出。

使用方式

创建需要使用托管代码的类并继承BackgroundService

public class HostedTest : BackgroundService

{

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)

    {

        await Task.Delay(5000);

        string s = await File.ReadAllTextAsync(@"D:NoteJQuery1-jQuery入门.md");

        await Task.Delay(20000);

        Console.WriteLine(s);

    }

}

在Program文件注册托管代码

builder.Services.AddHostedService<HostedTest>();

托管服务是以单例的生命周期注册到依赖注入容器中的。因此不能注入生命周期为范围或者瞬态的服务。

比如注入EF Core的上下文的话,程序就会抛出异常。

可以通过构造方法注入一个IServiceScopeFactory服务,它可以用来创建一个IServiceScope对象,这样我们就可以通过IServiceScope来创建短生命周期的服务了。记得在Dispose中释放IServiceScope。

public class HostedTest : BackgroundService

{

    private readonly IServiceScope _service;

    private readonly ILogger<HostedTest> logger;

 

    public HostedTest(IServiceScopeFactory service)

    {

        _service = service.CreateScope();

        var sp = _service.ServiceProvider;

        this.logger = sp.GetRequiredService<ILogger<HostedTest>>();

    }

 

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)

    {

        await Task.Delay(5000);

        string s = await File.ReadAllTextAsync(@"D:NoteJQuery1-jQuery入门.md");

        await Task.Delay(1000);

        Console.WriteLine(s);

        logger.LogInformation(s);

    }

    public override void Dispose()

    {

        base.Dispose();

        _service.Dispose();

    }

}

托管服务的异常问题

1、从.NET 6开始,当托管服务中发生未处理异常的时候,程序就会自动停止并退出。可以把HostOptions.BackgroundServiceExceptionBehavior设置为Ignore,程序会忽略异常,而不是停止程序。不过推荐采用默认的设置,因为“异常应该被妥善的处理,而不是被忽略”。

2、要在ExecuteAsync方法中把代码用try……catch包裹起来,当发生异常的时候,记录日志中或发警报等。

protected override async Task ExecuteAsync(CancellationToken stoppingToken)

{

    try

    {

        await Task.Delay(5000);

        string s = await File.ReadAllTextAsync(@"D:NoteJQuery1-jQuery入门.md");

        await Task.Delay(1000);

        Console.WriteLine(s);

        logger.LogInformation(s);

    }

    catch (Exception ex)

    {

        logger.LogError("异常处理:"+ex.Message);

    }

}

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。