学海无涯

导航

统计

BackgroundService 利用托管服务执行后台代码

ASP.NET Core 中提供了托管服务 (hosted service) 来供我们编写运行在后台的代码。

只要继承抽象类 BackgroundService ,并实现方法 ExecuteAsync() ,如果有需要释放的资源,可以写在Dispose()方法中

 一、除了日志外不需要注入其它服务的后台服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class DemoBgService : BackgroundService
   {
       private readonly ILogger<DemoBgService> _logger;
 
       public DemoBgService(ILogger<DemoBgService> logger)
       {
           _logger = logger;
       }
 
       protected override async Task ExecuteAsync(CancellationToken stoppingToken)
       {<br>      try{
           await Task.Delay(5000);
           string s = await File.ReadAllTextAsync(@"e://1.txt");
           await Task.Delay(2000);
           _logger.LogInformation(s);<br>        }<br>        catch (Exception ex)<em id="__mceDel">                {
                   _logger.LogError(ex, "执行后台服务失败");
                   await Task.Delay(1000);
               }</em>        }
   }

注册服务

1
services.AddHostedService<DemoBgService>();

二、需要注入其它服务的后台服务

因为注入的后台服务是单例,所以不能直接在构造函数中注入其它服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
public class DemoBgService : BackgroundService
   {
       private readonly ILogger<DemoBgService> _logger;
       private readonly IdDbContext _dbContext;
       private readonly IServiceScope _serviceScope;
       public DemoBgService(ILogger<DemoBgService> logger, IServiceScopeFactory scopeFactory)
       {
           _logger = logger;
           _serviceScope = scopeFactory.CreateScope();
           var sp = _serviceScope.ServiceProvider;
           _dbContext = sp.GetRequiredService<IdDbContext>();
       }
 
       protected override async Task ExecuteAsync(CancellationToken stoppingToken)
       {
           while (!stoppingToken.IsCancellationRequested)
           {
               try
               {
                   await DoExecuteAsync();
                   await Task.Delay(5000);
               }
               catch (Exception ex)
               {
                   _logger.LogError(ex, "获取用户统计数据失败");
                   await Task.Delay(1000);
               }
           }
       }
       private async Task DoExecuteAsync()
       {
           var items = _dbContext.Users.GroupBy(u => u.CreationTime)
               .Select(g => new { Date = g.Key, Count = g.Count() });
           StringBuilder sb = new StringBuilder();
           sb.AppendLine($"Date:{DateTime.Now}");
           foreach (var item in items)
           {
               sb.Append(item.Date).AppendLine($":{item.Count}");
           }
           await File.WriteAllTextAsync("E://1.txt", sb.ToString());
           _logger.LogInformation("导出完成");
       }
       public override void Dispose()
       {
           base.Dispose();
           _serviceScope.Dispose();
       }
   }

  如果要执行定时任务,例如:“每天凌晨3点执行数据备份任务”或者“每月初执行一次报表统计任务”等,可以使用 Hangfire、Quartz.Net 专业的定时任务开源项目。

posted on   宁静致远.  阅读(572)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
点击右上角即可分享
微信分享提示