当前位置: 首页 > article >正文

ASP.NET Core托管服务

目录

托管服务的异常问题

托管服务中使用DI

托管服务案例:数据的定时导出


场景,代码运行在后台。比如服务器启动的时候在后台预先加载数据到缓存,每天凌晨3点把数据导出到备份数据库,每隔5秒钟在两张表之间同步一次数据。托管服务实现IHostedService接口,一般编写从BackgroundService继承的类。如需定时操作,可使用Hangfire框架。

builder.Services.AddHostedService<HostedService>();

托管服务的异常问题

  1. 从.NET 6开始,当托管服务中发生未处理异常的时候,程序就会自动停止并退出。可以把HostOptions.BackgroundServiceExceptionBehavior设置为Ignore,程序会忽略异常,而不是停止程序。不过推荐采用默认的设置,因为“异常应该被妥善的处理,而不是被忽略”。
  2. 要在ExecuteAsync方法中把代码用try……catch包裹起来,当发生异常的时候,记录日志中或发警报等。

托管服务中使用DI

  1. 托管服务是以单例的生命周期注册到依赖注入容器中的。因此不能注入生命周期为范围或者瞬态的服务。比如注入EF Core的上下文的话,程序就会抛出异常。
  2. 可以通过构造方法注入一个IServiceScopeFactory服务,它可以用来创建一个IServiceScope对象,这样我们就可以通过IServiceScope来创建短生命周期的服务了。记得在Dispose中释放IServiceScope。
public class HostedService : BackgroundService
{
    private IServiceScope serviceScope;
    public HostedService(IServiceScopeFactory serviceScopeFactory)
    {
        this.serviceScope = serviceScopeFactory.CreateScope();
    }

    public override void Dispose()
    {
        this.serviceScope.Dispose();
        base.Dispose();
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        try
        {
            var testService = serviceScope.ServiceProvider.GetRequiredService<TestService>();

            Console.WriteLine("HostService1启动" + testService.Add(1, 1));
            await Task.Delay(3000);
            string txt = await File.ReadAllTextAsync("f:/1.txt");
            Console.WriteLine("文件读取完成");
            string s = null;
            s.ToString();
            await Task.Delay(3000);
            Console.WriteLine(txt);
        }
        catch (Exception ex)
        {
            Console.WriteLine("服务中出现未处理异常" + ex);
        }
    }
}
public class TestService
{
    public int Add(int a, int b)
    {
        return a + b;
    }
}
builder.Services.AddHostedService<HostedService>();
builder.Services.AddScoped<TestService>();

托管服务案例:数据的定时导出

常驻后台的托管服务并不需要特殊的技术,我们只要让ExecuteAsync中的代码一直执行不结束就行了。实现的功能就是每隔五秒钟统计一次数据库中的数据,将数据写入文本。

builder.Services.AddHostedService<ScheduledService>();

public class ScheduledService : BackgroundService
{
    private readonly IServiceScope serviceScope;
    public ScheduledService(IServiceScopeFactory serviceScopeFactory)
    {
        this.serviceScope = serviceScopeFactory.CreateScope();
    }
    public override void Dispose()
    {
        this.serviceScope.Dispose();
        base.Dispose();
    }
    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        try
        {
            var dbCtx = serviceScope.ServiceProvider.GetRequiredService<MyDbContext>();
            while (!stoppingToken.IsCancellationRequested)
            {
                var count = dbCtx.Users.LongCount();
                await File.WriteAllTextAsync("F:/1.txt", count.ToString());
                await Task.Delay(5000);
            }
            Console.WriteLine("导出成功" + DateTime.Now);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);
        }
    }
}

http://www.kler.cn/a/538866.html

相关文章:

  • 学习 PostgreSQL 流复制
  • 多路文件IO
  • NIO--ByteBuffer组件
  • HTTP协议学习大纲
  • 如何在Windows中配置MySQL?
  • AtCoder Beginner Contest 392(A-G)题解
  • Java 线程池内部任务出异常后,如何知道是哪个线程出了异常
  • 【Python】元组
  • Deepseek访问受限?换种方式轻松使用
  • 22.3、IIS安全分析与增强
  • 【React】实现TagInput输入框,可以输入多个邮箱并校验是否合法
  • Agent论文阅读:NormEnforcement with a Soft Touch: Faster Emergence, Happier Agents
  • 阿里云服务器XShell连接启动java -jar xxx.jar后退出ssh,后端也退出,使用screen 亲测管用!
  • 【Jetson Nano安装gpu版pytroch1.7torchvision0.8.1 in python3.8 跑 Ultralytics YOLO】
  • 关于预训练后训练、LLM和视频大模型相关学习记录
  • 周报1.0
  • 鸿蒙音视频播放器:libwlmedia
  • 如何解决 Linux 文件系统挂载失败的问题
  • vue print 打印
  • 11.递归遍历、迭代遍历、统一迭代、层序遍历
  • Excel大数据量导入导出
  • React 生命周期函数详解
  • antd-react日期组件disabledDate不可选择的日期 (置灰)属性
  • Nginx进阶篇 - nginx多进程架构详解
  • SpringBoot速成(八)登录实战:未登录不能访问 P5-P8
  • Vue 3 + Vite + JS 项目中实现组件全局自动化注册的魔法,极致组件自动化注册方案,开发效率飙升300%。