前言
最近有个需求是固定时间取得特定资料进行修改,在查询相关资料之后决定使用 ASP.NET Core Generic Host
为出发,在搭配 .NET 中热门的排程套件 Quartz.Net
,测试完毕之后再將程式註册为 Windows Service
服务就可满足使用者的需求,这篇文章是整理开发时的重点流程为系列文,给有需要使用 ASP.NET Core 开发排程相关应用程式需求的朋友一些参考,若有问题或是错误的地方欢迎各位高手给予指导。
Generic Host
在过去处理 HTTP
请求时可以使用 WebHostBuilder
类別来处理,在开发 ASP.NET Core 应用程式设定及建立 WebHost
以及使用 Kestrel
服务接收请求並处理应用程式的生命週期,使用 DI 设定或配置 Logging
等重要功能,但並非所有的需求都依赖於 HTTP ,如 BackgroundService
背景执行程序或是处理 Queue
的资料等工作就不需要依赖於 HTTP 请求,从 ASP.NET Core 2.1
开始提供 Generic Host (泛型主机),提供开发者可以有新的选项来开发没有 HTTP 请求的应用程式,可以透过 MSDN 示意图了解
CreateHostedBuilder
如果选择 Generic Host
开发程式,建议先了解 WebHostBuilder
背后预设配置的设定方式以及做了哪些事情,在之前 ASP.NET Core 环境佈署设定 appsettings.json 文章中有介绍过,建立新的 ASP.NTE Core 应用程式预设模板可以看到在 program.cs 中內建 CreateWebHostBuilder
,此方法代码中设定很多预设的配置,像是指定读取资料夹中的 appsetting.json、环境变数、logging 设定、使用 Kestrel Server等预设內容。了解 WebHostBuilder 是如何设定的也有了基本概念,就可以发现有部分內容在 HostBuilder
是可以共用的,就可以开始著手开发 Generic Host
程式,首先先建立新的 ASP.NET Core Console 专案,並开启 Program.cs 建立 CreateHostBuilder
运算式,代码如下
private static IHostBuilder CreateHostBuilder() =>
new HostBuilder()
.ConfigureHostConfiguration(configHost =>
{
// setup Host configuration
configHost.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("hostsettings.json", optional: true)
.AddEnvironmentVariables();
})
.ConfigureAppConfiguration((hostContext, configApp) =>
{
// setup App configuration
configApp.AddJsonFile("appsettings.json")
.AddJsonFile(
$"appsettings.{hostContext.HostingEnvironment.EnvironmentName}.json",
optional: true, reloadOnChange: true)
.AddEnvironmentVariables();
})
.ConfigureServices((services =>
{
services.Configure<HostOptions>(option =>
{
option.ShutdownTimeout = TimeSpan.FromSeconds(30);
});
}))
.ConfigureLogging((hostingContext, logging) =>
{
// Get Config from Logging section
logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"))
.AddEventLog();
if (hostingContext.HostingEnvironment.IsDevelopment())
{
logging.AddConsole();
}
});
將 TimedHostedService
加入到 Service
中
.ConfigureServices((hostContext, services) =>
{
// ...
services.AddHostedService<TimedHostedService>();
}
在 main
方法中直接使用 RunConsoleAync
static async Task Main(string[] args)
{
try
{
var builder = CreateHostBuilder();
await builder.RunConsoleAsync();
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
这边需要注意的是由於 async
是 C# 7.1 开始支援的功能,因此如果专案预设编译需要设定为使用 C# 7.1 来进行编译,否则上面代码可能会造成编译错误,错误讯息为 : Feature ‘default literal’ is not available in C# 7.0. Please use language version 7.1 or greater.,解决方法只要去设定专案编译 C# 版本即可,设定方式为 专案点选右键 > property > Advance
完成了基本功能设定,按下执行可以看到 Console 跑出来的结果如下
这一篇介绍 Generic Host
基本设定,其中包含应用程式起来时候的配置,为了避免一篇文章太冗长看了想睡觉,下一篇再来介绍剩下的部分也就是 Quartz.Net
的方式,也可以趁这机会稍微消化一下,看是否有不懂的地方也欢迎隨时提出来,谢谢