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

登陆国外的网站要这么做重庆seo网站推广工具

登陆国外的网站要这么做,重庆seo网站推广工具,网站如何备份数据,麦进斗网站建设在这篇文章中#xff0c;我将介绍如何使用ASP.NET Core托管服务运行Quartz.NET作业。这样的好处是我们可以在应用程序启动和停止时很方便的来控制我们的Job的运行状态。接下来我将演示如何创建一个简单的 IJob#xff0c;一个自定义的 IJobFactory和一个在应用程序运行时就开… 在这篇文章中我将介绍如何使用ASP.NET Core托管服务运行Quartz.NET作业。这样的好处是我们可以在应用程序启动和停止时很方便的来控制我们的Job的运行状态。接下来我将演示如何创建一个简单的 IJob一个自定义的 IJobFactory和一个在应用程序运行时就开始运行的QuartzHostedService。我还将介绍一些需要注意的问题即在单例类中使用作用域服务。简介-什么是Quartz.NET在开始介绍什么是Quartz.NET前先看一下下面这个图这个图基本概括了Quartz.NET的所有核心内容。注此图为百度上获取旨在学习交流使用如有侵权联系后删除。以下来自他们的网站的描述Quartz.NET是功能齐全的开源作业调度系统适用于从最小型的应用程序到大型企业系统。对于许多ASP.NET开发人员来说它是首选用作在计时器上以可靠、集群的方式运行后台任务的方法。将Quartz.NET与ASP.NET Core一起使用也非常相似-因为Quartz.NET支持.NET Standard 2.0因此您可以轻松地在应用程序中使用它。Quartz.NET有两个主要概念Job。这是您要按某个特定时间表运行的后台任务。Scheduler。这是负责基于触发器基于时间的计划运行作业。ASP.NET Core通过托管服务对运行“后台任务”具有良好的支持。托管服务在ASP.NET Core应用程序启动时启动并在应用程序生命周期内在后台运行。通过创建Quartz.NET托管服务您可以使用标准ASP.NET Core应用程序在后台运行任务。虽然可以创建“定时”后台服务例如每10分钟运行一次任务但Quartz.NET提供了更为强大的解决方案。通过使用Cron触发器您可以确保任务仅在一天的特定时间例如凌晨2:30运行或仅在特定的几天运行或任意组合运行。它还允许您以集群方式运行应用程序的多个实例以便在任何时候只能运行一个实例高可用。在本文中我将介绍创建Quartz.NET作业的基本知识并将其调度为在托管服务中的计时器上运行。安装Quartz.NETQuartz.NET是.NET Standard 2.0 NuGet软件包因此非常易于安装在您的应用程序中。对于此测试我创建了一个ASP.NET Core项目并选择了Empty模板。您可以使用dotnet add package Quartz来安装Quartz.NET软件包。这时候查看该项目的.csproj应如下所示Project SdkMicrosoft.NET.Sdk.WebPropertyGroupTargetFrameworknetcoreapp3.1/TargetFramework/PropertyGroupItemGroupPackageReference IncludeQuartz Version3.0.7 //ItemGroup /Project创建一个IJob对于我们正在安排的实际后台工作我们将通过向注入的ILogger中写入“ hello world”来进行实现进而向控制台输出结果。您必须实现包含单个异步Execute()方法的Quartz接口IJob。请注意这里我们使用依赖注入将日志记录器注入到构造函数中。using Microsoft.Extensions.Logging; using Quartz; using System; using System.Threading.Tasks; namespace QuartzHostedService {[DisallowConcurrentExecution]public class HelloWorldJob : IJob{private readonly ILoggerHelloWorldJob _logger;public HelloWorldJob(ILoggerHelloWorldJob logger){_logger logger ?? throw new ArgumentNullException(nameof(logger));}public Task Execute(IJobExecutionContext context){_logger.LogInformation(Hello world by yilezhu at {0}!,DateTime.Now.ToString(yyyy-MM-dd HH:mm:ss));return Task.CompletedTask;}} }我还用[DisallowConcurrentExecution]属性装饰了该作业。该属性可防止Quartz.NET尝试同时运行同一作业。创建一个IJobFactory接下来我们需要告诉Quartz如何创建IJob的实例。默认情况下Quartz将使用Activator.CreateInstance创建作业实例从而有效的调用new HelloWorldJob()。不幸的是由于我们使用构造函数注入因此无法正常工作。相反我们可以提供一个自定义的IJobFactory挂钩到ASP.NET Core依赖项注入容器IServiceProvider中using Microsoft.Extensions.DependencyInjection; using Quartz; using Quartz.Spi; using System; namespace QuartzHostedService {public class SingletonJobFactory : IJobFactory{private readonly IServiceProvider _serviceProvider;public SingletonJobFactory(IServiceProvider serviceProvider){_serviceProvider serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider));}public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler){return _serviceProvider.GetRequiredService(bundle.JobDetail.JobType) as IJob;}public void ReturnJob(IJob job){}} }该工厂将一个IServiceProvider传入构造函数中并实现IJobFactory接口。这里最重要的方法是NewJob()方法。在这个方法中工厂必须返回Quartz调度程序所请求的IJob。在此实现中我们直接委托给IServiceProvider并让DI容器找到所需的实例。由于GetRequiredService的非泛型版本返回的是一个对象因此我们必须在末尾将其强制转换成IJob。该ReturnJob方法是调度程序尝试返回即销毁工厂创建的作业的地方。不幸的是使用内置的IServiceProvider没有这样做的机制。我们无法创建适合Quartz API所需的新的IScopeService因此我们只能创建单例作业。这个很重要。使用上述实现仅对创建单例或瞬态的IJob实现是安全的。配置作业我在IJob这里仅显示一个实现但是我们希望Quartz托管服务是适用于任何数量作业的通用实现。为了解决这个问题我们创建了一个简单的DTO JobSchedule用于定义给定作业类型的计时器计划using System; using System.ComponentModel; namespace QuartzHostedService {/// summary/// Job调度中间对象/// /summarypublic class JobSchedule{public JobSchedule(Type jobType, string cronExpression){this.JobType jobType ?? throw new ArgumentNullException(nameof(jobType));CronExpression cronExpression ?? throw new ArgumentNullException(nameof(cronExpression));}/// summary/// Job类型/// /summarypublic Type JobType { get; private set; }/// summary/// Cron表达式/// /summarypublic string CronExpression { get; private set; }/// summary/// Job状态/// /summarypublic JobStatus JobStatu { get; set; } JobStatus.Init;}/// summary/// Job运行状态/// /summarypublic enum JobStatus:byte{[Description(初始化)]Init0,[Description(运行中)]Running1,[Description(调度中)]Scheduling 2,[Description(已停止)]Stopped 3,} }这里的JobType是该作业的.NET类型在我们的例子中就是HelloWorldJob并且CronExpression是一个Quartz.NET的Cron表达。Cron表达式允许复杂的计时器调度因此您可以设置下面复杂的规则例如“每月5号和20号在上午8点至10点之间每半小时触发一次”。只需确保检查文档即可因为并非所有操作系统所使用的Cron表达式都是可以互换的。我们将作业添加到DI并在Startup.ConfigureServices()中配置其时间表using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Quartz; using Quartz.Impl; using Quartz.Spi; namespace QuartzHostedService {public class Startup{public void ConfigureServices(IServiceCollection services){//添加Quartz服务services.AddSingletonIJobFactory, SingletonJobFactory();services.AddSingletonISchedulerFactory, StdSchedulerFactory();//添加我们的Jobservices.AddSingletonHelloWorldJob();services.AddSingleton(new JobSchedule(jobType: typeof(HelloWorldJob), cronExpression: 0/5 * * * * ?));}public void Configure(IApplicationBuilder app, IWebHostEnvironment env){......}} }此代码将四个内容作为单例添加到DI容器SingletonJobFactory 是前面介绍的用于创建作业实例。一个ISchedulerFactory的实现使用内置的StdSchedulerFactory它可以处理调度和管理作业该HelloWorldJob作业本身一个类型为HelloWorldJob并包含一个五秒钟运行一次的Cron表达式的JobSchedule的实例化对象。现在我们已经完成了大部分基础工作只缺少一个将他们组合在一起的、QuartzHostedService了。创建QuartzHostedService该QuartzHostedService是IHostedService的一个实现设置了Quartz调度程序并且启用它并在后台运行。由于Quartz的设计我们可以在IHostedService中直接实现它而不是从基BackgroundService类派生更常见的方法。该服务的完整代码在下面列出稍后我将对其进行详细描述。using Microsoft.Extensions.Hosting; using Quartz; using Quartz.Spi; using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; namespace QuartzHostedService {public class QuartzHostedService : IHostedService{private readonly ISchedulerFactory _schedulerFactory;private readonly IJobFactory _jobFactory;private readonly IEnumerableJobSchedule _jobSchedules;public QuartzHostedService(ISchedulerFactory schedulerFactory, IJobFactory jobFactory, IEnumerableJobSchedule jobSchedules){_schedulerFactory schedulerFactory ?? throw new ArgumentNullException(nameof(schedulerFactory));_jobFactory jobFactory ?? throw new ArgumentNullException(nameof(jobFactory));_jobSchedules jobSchedules ?? throw new ArgumentNullException(nameof(jobSchedules));}public IScheduler Scheduler { get; set; }public async Task StartAsync(CancellationToken cancellationToken){Scheduler await _schedulerFactory.GetScheduler(cancellationToken);Scheduler.JobFactory _jobFactory;foreach (var jobSchedule in _jobSchedules){var job CreateJob(jobSchedule);var trigger CreateTrigger(jobSchedule);await Scheduler.ScheduleJob(job, trigger, cancellationToken);jobSchedule.JobStatu JobStatus.Scheduling;}await Scheduler.Start(cancellationToken);foreach (var jobSchedule in _jobSchedules){jobSchedule.JobStatu JobStatus.Running;}}public async Task StopAsync(CancellationToken cancellationToken){await Scheduler?.Shutdown(cancellationToken);foreach (var jobSchedule in _jobSchedules){jobSchedule.JobStatu JobStatus.Stopped;}}private static IJobDetail CreateJob(JobSchedule schedule){var jobType schedule.JobType;return JobBuilder.Create(jobType).WithIdentity(jobType.FullName).WithDescription(jobType.Name).Build();}private static ITrigger CreateTrigger(JobSchedule schedule){return TriggerBuilder.Create().WithIdentity(${schedule.JobType.FullName}.trigger).WithCronSchedule(schedule.CronExpression).WithDescription(schedule.CronExpression).Build();}} }该QuartzHostedService有三个依存依赖项我们在Startup中配置的ISchedulerFactory和IJobFactory还有一个就是IEnumerableJobSchedule。我们仅向DI容器中添加了一个JobSchedule对象即HelloWorldJob但是如果您在DI容器中注册更多的工作计划它们将全部注入此处当然你也可以通过数据库来进行获取再加以UI控制是不是就实现了一个可视化的后台调度了呢自己想象吧~。StartAsync方法将在应用程序启动时被调用因此这里就是我们配置Quartz的地方。我们首先一个IScheduler的实例将其分配给属性以供后面使用然后将注入的JobFactory实例设置给调度程序 public async Task StartAsync(CancellationToken cancellationToken){Scheduler await _schedulerFactory.GetScheduler(cancellationToken);Scheduler.JobFactory _jobFactory;...}接下来我们循环注入作业计划并为每一个作业使用在类的结尾处定义的CreateJob和CreateTrigger辅助方法在创建一个Quartz的IJobDetail和ITrigger。如果您不喜欢这部分的工作方式或者需要对配置进行更多控制则可以通过按需扩展JobScheduleDTO 来轻松自定义它。public async Task StartAsync(CancellationToken cancellationToken) {// ...foreach (var jobSchedule in _jobSchedules){var job CreateJob(jobSchedule);var trigger CreateTrigger(jobSchedule);await Scheduler.ScheduleJob(job, trigger, cancellationToken);jobSchedule.JobStatu JobStatus.Scheduling;}// ... } private static IJobDetail CreateJob(JobSchedule schedule) {var jobType schedule.JobType;return JobBuilder.Create(jobType).WithIdentity(jobType.FullName).WithDescription(jobType.Name).Build(); } private static ITrigger CreateTrigger(JobSchedule schedule) {return TriggerBuilder.Create().WithIdentity(${schedule.JobType.FullName}.trigger).WithCronSchedule(schedule.CronExpression).WithDescription(schedule.CronExpression).Build(); }最后一旦所有作业都被安排好您就可以调用它的Scheduler.Start()来在后台实际开始Quartz.NET计划程序的处理。当应用程序关闭时框架将调用StopAsync()此时您可以调用Scheduler.Stop()以安全地关闭调度程序进程。public async Task StopAsync(CancellationToken cancellationToken) {await Scheduler?.Shutdown(cancellationToken); }您可以使用AddHostedService()扩展方法在托管服务Startup.ConfigureServices中注入我们的后台服务public void ConfigureServices(IServiceCollection services) {// ...services.AddHostedServiceQuartzHostedService(); }如果运行该应用程序则应该看到每隔5秒运行一次后台任务并写入控制台中或配置日志记录的任何地方在作业中使用作用域服务这篇文章中描述的实现存在一个大问题您只能创建Singleton或Transient作业。这意味着您不能使用注册为作用域服务的任何依赖项。例如您将无法将EF Core的 DatabaseContext注入您的IJob实现中因为您会遇到Captive Dependency问题。解决这个问题也不是很难您可以注入IServiceProvider并创建自己的作用域。例如如果您需要在HelloWorldJob中使用作用域服务则可以使用以下内容public class HelloWorldJob : IJob {// 注入DI providerprivate readonly IServiceProvider _provider;public HelloWorldJob( IServiceProvider provider){_provider provider;}public Task Execute(IJobExecutionContext context){// 创建一个新的作用域using(var scope _provider.CreateScope()){// 解析你的作用域服务var service scope.ServiceProvider.GetServiceIScopedService();_logger.LogInformation(Hello world by yilezhu at {0}!,DateTime.Now.ToString(yyyy-MM-dd HH:mm:ss));}return Task.CompletedTask;} }这样可以确保在每次运行作业时都创建一个新的作用域因此您可以在IJob中检索并处理作用域服务。糟糕的是这样的写法确实有些混乱。在下一篇文章中我将展示另一种比较优雅的实现方式它更简洁有兴趣的可以关注下“DotNetCore实战”公众号第一时间获取更新。总结在这篇文章中我介绍了Quartz.NET并展示了如何使用它在ASP.NET Core中的IHostedService中来调度后台作业。这篇文章中显示的示例最适合单例或瞬时作业这并不理想因为使用作用域服务显得很笨拙。在下一篇文章中我将展示另一种比较优雅的实现方式它更简洁并使得使用作用域服务更容易,有兴趣的可以关注下“DotNetCore实战”公众号第一时间获取更新。首发地址https://www.yuque.com/yilezhu/etg3w3/aspnetcore-hostservice-quartz-net-1参考英文地址https://andrewlock.net/creating-a-quartz-net-hosted-service-with-asp-net-core/往期精彩回顾【推荐】.NET Core开发实战视频课程 ★★★.NET Core实战项目之CMS 第一章 入门篇-开篇及总体规划【.NET Core微服务实战-统一身份认证】开篇及目录索引Redis基本使用及百亿数据量中的使用技巧分享附视频地址及观看指南.NET Core中的一个接口多种实现的依赖注入与动态选择看这篇就够了10个小技巧助您写出高性能的ASP.NET Core代码用abp vNext快速开发Quartz.NET定时任务管理界面现身说法实际业务出发分析百亿数据量下的多表查询优化关于C#异步编程你应该了解的几点建议C#异步编程看这篇就够了给我好看 您看此文用  · 秒转发只需1秒呦~ 好看你就点点我
http://www.pierceye.com/news/495154/

相关文章:

  • 网站搜索优化官网网站建设在电子商务中的作用的看法
  • 网站推广费用价格html大屏展示模板
  • 编辑网站用什么软件网站开发人员职责
  • 网站搜索引擎提交wordpress发布站点
  • 阳春网站建设天水网站seo
  • 仙桃市建设局网站wordpress链接前面的图标
  • 温州市城乡建设建档案馆网站公司装修费用可以一次性入账吗
  • 房地产开发公司网站宠物网页设计模板
  • 网站备案信息可以改吗中国做二手房最大的网站
  • 设计 企业网站罗湖网站-建设深圳信科
  • 太原自助模板建站手机版电脑qq登录入口
  • 公司网站建设哪家比较好app 网站
  • 建设银行个人网站打不开个人主页模板下载
  • 山西建设公司网站wordpress视频适应手机端
  • 原型样网站做一般的公司门户网站投资额
  • 南宁百度网站公司电话网站配置优化
  • 德州网站建设的公司免费注册公司怎么注册
  • 成都开发网站建设中国建设规划采购网站
  • 企业网站建设应避免数据孤岛深圳东莞网站建设
  • pk10网站怎么做郑州seo费用
  • 菏泽市建设局网站电话网站建设服务咨询
  • 购物网站模版广州外贸网络推广
  • 高碑店网站网站建设手机软件开发的模式
  • 公司网站开发国内外现状网络营销外包团队哪些好
  • 淘客网站怎么建立如何用api做网站
  • 合肥网站建设ahyedawordpress主题安全
  • 网站建设实训室介绍东莞seo广告宣传
  • 公职人员可以做公益网站吗aws网站建设
  • 什么叫高端网站定制广州建筑公司
  • 全新网站如何做百度竞价网站制作现状解决方案