.NET Core基于Generic Host实现后台任务方法教程

编程学习 2021-07-04 22:41www.dzhlxh.cn编程入门
这篇文章主要给大家介绍了关于.NET Core基于Generic Host实现后台任务的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们狼蚁网站SEO优化随着长沙网络推广来一起学习学习吧

前言

很多时候,后台任务对我们来说是一个利器,帮我们在后面处理了成千上万的事情。

在.NET Framework时代,我们可能比较多的就是一个项目,会有一到多个对应的Windows服务,这些Windows服务就可以当作是我们所说的后台任务了。

我喜欢将后台任务分为两大类,一类是不停的跑,好比MQ的消费者,RPC的服务端。另一类是定时的跑,好比定时任务。

那么在.NET Core时代是不是有一些不同的解决方案呢?答案是肯定的。

Generic Host就是其中一种方案,也是本文的主角。

什么是Generic Host

Generic Host是ASP.NET Core 2.1中的新增功能,它的目的是将HTTP管道从Web Host的API中分离出来,从而启用更多的Host方案。

现在2.1版本的Asp.Net Core中,有了两种可用的Host。

–适用于托管Web程序的Host,就是我们所熟悉的在Asp.Net Core应用程序的Mai函数中用CreateWebHostBuilder创建出来的常用的WebHost。

(ASP.NET Core 2.1版本才有) – 适用于托管非 Web 应用(例如,运行后台任务的应用)。 在未来的版本中,通用主机将适用于托管任何类型的应用,包括 Web 应用。 通用主机最终将取代 Web 主机,这大概也是这种类型的主机叫做通用主机的原因。

这样可以让基于Generic Host的一些特性延用一些基础的功能。如:如配置、依赖关系注入和日志等。

Generic Host更倾向于通用性,换句话就是说,我们即可以在Web项目中使用,也可以在非Web项目中使用!

虽然有时候后台任务混杂在Web项目中并不是一个太好的选择,但也并不失是一个解决方案。尤其是在资源并不充足的时候。

比较好的做法还是让其独立出来,让它的职责更加单一。

狼蚁网站SEO优化就先来看看如何创建后台任务吧。

后台任务示例

我们先来写两个后台任务(一个一直跑,一个定时跑),体验一下这些后台任务要怎么上手,同样也是我们后面要使用到的。

这两个任务统一继承BackgroundService这个抽象类,而不是IHostedService这个接口。后面会说到两者的区别。

1、一直跑的后台任务

先上代码

public class PrinterHostedService2 : BackgroundService
{
 private readonly ILogger _logger;
 private readonly AppSettings _settings;

 public PrinterHostedService2(ILoggerFactory loggerFactory, IOptionsSnapshot<AppSettings> options)
 {
 this._logger = loggerFactory.CreateLogger<PrinterHostedService2>();
 this._settings = options.Value;
 }

 public override Task StopAsync(CancellationToken cancellationToken)
 {
 _logger.LogInformation("Printer2 is stopped");
 return Task.CompletedTask;
 }

 protected override async Task ExecuteAsync(CancellationToken stoppingToken)
 {
 while (!stoppingToken.IsCancellationRequested)
 {
  _logger.LogInformation($"Printer2 is working. {_settings.PrinterDelaySecond}");
  await Task.Delay(TimeSpan.FromSeconds(_settings.PrinterDelaySecond), stoppingToken);
 }
 }
}

来看看里面的细节。

我们的这个服务继承了BackgroundService,就一定要实现里面的ExecuteAsync,至于StartAsync和StopAsync等方法可以选择性的override。

我们ExecuteAsync在里面就是输出了一下日志,然后休眠在配置文件中指定的秒数。

这个任务可以说是最简单的例子了,其中还用到了依赖注入,如果想在任务中注入数据仓储之类的,应该就不需要再多说了。

同样的方式再写一个定时的。

定时跑的后台任务

这里借助了Timer来完成定时跑的功能,同样的还可以结合Quartz来完成。

public class TimerHostedService : BackgroundService
{
 //other ...
 
 private Timer _timer;

 protected override Task ExecuteAsync(CancellationToken stoppingToken)
 {
 _timer = new Timer(DoWork, null, TimeSpan.Zero, TimeSpan.FromSeconds(_settings.TimerPeriod));
 return Task.CompletedTask;
 }

 private void DoWork(object state)
 {
 _logger.LogInformation("Timer is working");
 }

 public override Task StopAsync(CancellationToken cancellationToken)
 {
 _logger.LogInformation("Timer is stopping");
 _timer?.Change(Timeout.Infinite, 0);
 return base.StopAsync(cancellationToken);
 }

 public override void Dispose()
 {
 _timer?.Dispose();
 base.Dispose();
 }
}

和第一个后台任务相比,没有太大的差异。

狼蚁网站SEO优化我们先来看看如何用控制台的形式来启动这两个任务。

控制台形式

这里会同时引入NLog来记录任务跑的日志,方便我们观察。

Main函数的代码如下:

class Program
{
 static async Task Main(string[] args)
 {
 var builder = new HostBuilder()
  //logging
  .ConfigureLogging(factory =>
  {
  //use nlog
  factory.AddNLog(new NLogProviderOptions { CaptureMessageTemplates = true, CaptureMessageProperties = true });
  NLog.LogManager.LoadConfiguration("nlog.config");
  })
  //host config
  .ConfigureHostConfiguration(config =>
  {
  //command line
  if (args != null)
  {
   config.AddCommandLine(args);
  }
  })
  //app config
  .ConfigureAppConfiguration((hostContext, config) =>
  {
  var env = hostContext.HostingEnvironment;
  config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
   .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);

  config.AddEnvironmentVariables();

  if (args != null)
  {
   config.AddCommandLine(args);
  }
  })
  //service
  .ConfigureServices((hostContext, services) =>
  {
  services.AddOptions();
  services.Configure<AppSettings>(hostContext.Configuration.GetSection("AppSettings"));

  //basic usage
  services.AddHostedService<PrinterHostedService2>();
  services.AddHostedService<TimerHostedService>();
  }) ;

 //console 
 await builder.RunConsoleAsync();

 ////start and wait for shutdown
 //var host = builder.Build();
 //using (host)
 //{
 // await host.StartAsync();

 // await host.WaitForShutdownAsync();
 / 

Copyright © 2016-2025 www.dzhlxh.cn 金源码 版权所有 Power by

网站模板下载|网络推广|微博营销|seo优化|视频营销|网络营销|微信营销|网站建设|织梦模板|小程序模板