基于Asp.Net Core 5.0依赖Quartz.Net框架编写的任务调度web管理平台
源码地址: https://github.com/246850/Calamus.TaskScheduler
演示地址:http://47.101.47.193:1063/

1、Quartz.NET框架核心类
IScheduler:调度者
IJobDetail:任务
ITrigger:触发器
JobKey:任务/触发器标识
JobDataMap:数据包
2、邮件通知(FluentEmail类库)
_fluentEmail.To(to).Subject(subject).Body(body, true).SendAsync();
3、Quartz.NET宿主方式,依靠IHostedService后台服务执行
internal class QuartzHostedService : IHostedService
{
private readonly ISchedulerFactory schedulerFactory;
private readonly IOptions<QuartzHostedServiceOptions> options;
private IScheduler scheduler = null!; public QuartzHostedService(
ISchedulerFactory schedulerFactory,
IOptions<QuartzHostedServiceOptions> options)
{
this.schedulerFactory = schedulerFactory;
this.options = options;
} public async Task StartAsync(CancellationToken cancellationToken)
{
scheduler = await schedulerFactory.GetScheduler(cancellationToken);
await scheduler.Start(cancellationToken);
} public Task StopAsync(CancellationToken cancellationToken)
{
return scheduler.Shutdown(options.Value.WaitForJobsToComplete, cancellationToken);
}
}
4.Asp.Net Core 5.0集成
安装依赖包
Quartz
Quartz.AspNetCore
Quartz.Plugins.TimeZoneConverter
Quartz.Serialization.Json
FluentEmail.Core
FluentEmail.Smtp
Startup
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews(options =>
{
options.Filters.Add<GatewayResultFilterAttribute>(); // 通用执行结果包装处理过滤器
options.Filters.Add<GlobalExceptionFilterAttribute>(); // 全局异常过滤器
})
.AddJsonOptions(options =>
{
options.JsonSerializerOptions.Converters.Add(new DateTimeConverter()); // 日期格式化
})
.AddFluentValidation(config => // 请求模型参数验证
{
config.RunDefaultMvcValidationAfterFluentValidationExecutes = true; // false : 禁止默认模型验证
config.ValidatorOptions.CascadeMode = CascadeMode.Stop; // 不级联验证,第一个规则错误就停止
config.RegisterValidatorsFromAssemblyContaining<JobCreateOrUpdateValidator>();
});
services.AddHostedService<NLogHostService>(); // NLog 关闭服务
services.AddDistributedMemoryCache(); // 分布式缓存接口
services.AddSingleton(HtmlEncoder.Create(UnicodeRanges.All));// 解决中文乱码
services.AddHttpClient(); // IHttpClientFactory IConfigurationSection quartzConfiguration = Configuration.GetSection("Quartz"); // Quartz配置节点 /***********Quartz.NET*********/
services.AddTransient<HttpJob>(); // 注册job至容器,必须步骤
services.AddQuartz(config =>
{
config.UseTimeZoneConverter();
// 使用MicrosoftDependencyInjectionJobFactory工厂类从 容器 中创建job实例
config.UseMicrosoftDependencyInjectionJobFactory(options =>
{
options.AllowDefaultConstructor = false; // 禁止使用无参构建函数创建 job
options.CreateScope = false;
});
config.UseDefaultThreadPool(options =>
{
options.MaxConcurrency = 10; // 最大并发执行线程数
});
config.UsePersistentStore(options =>
{
options.UseProperties = false;
//options.UseBinarySerializer(); // 二进制序列化
options.UseJsonSerializer(); // json序列化
options.UseMySql(ado =>
{
ado.ConnectionString = quartzConfiguration["Database"];
ado.TablePrefix = quartzConfiguration["TablePrefix"]; // 默认值 QRTZ_
ado.ConnectionStringName = "Quartz.net";
});
}); // 监听器
config.AddSchedulerListener<DefaultSchedulerListener>();
config.AddJobListener<DefaultJobListener>();
config.AddTriggerListener<DefaultTriggerListener>(); // 启动NLog日志文件清除job
config.ScheduleJob<ClearNLogJob>(trigger =>
{
trigger.WithIdentity(NLogJobKey.NameKey, NLogJobKey.GroupKey).StartNow()
.WithCronSchedule("0 0 0 1/3 * ? ", cron => cron.WithMisfireHandlingInstructionFireAndProceed()); // 从每月1日开始,每3天执行一次
}, job =>
{
job.WithIdentity(NLogJobKey.NameKey, NLogJobKey.GroupKey)
.StoreDurably(false) // 是否持久化, 无关联触发器时是否移除,false:移除
.RequestRecovery() // 重启后是否恢复任务
.WithDescription("每3天清空NLog日志文件");
});
});
// IHostedService宿主启动 Quartz服务 services.AddSingleton<IHostedService, QuartzHostedService>()
services.AddQuartzServer(options =>
{
// when shutting down we want jobs to complete gracefully
options.WaitForJobsToComplete = true; // 等待任务执行完,再退出
}); /***********FluentEmail*********/
// 为了将邮件通知配置在job data上, 不使用自带的service注册方式
//services.AddFluentEmail(quartzConfiguration["Smtp:UserName"], "Quartz.NET任务调度通知")
// .AddRazorRenderer()
// .AddSmtpSender(quartzConfiguration["Smtp:Host"], Convert.ToInt32(quartzConfiguration["Smtp:Port"]), quartzConfiguration["Smtp:UserName"], quartzConfiguration["Smtp:Password"]);
services.AddTransient<IFluentEmail>(serviceProvider =>
{
IScheduler scheduler = serviceProvider.GetRequiredService<ISchedulerFactory>().GetScheduler().Result; JobKey key = new JobKey(EmailJobKeys.NameKey, EmailJobKeys.GroupKey);
if (!scheduler.CheckExists(key).Result)
{
JobDataMap dataMap = new JobDataMap();
dataMap.Put(EmailJobKeys.Host, "smtp.qq.com");
dataMap.Put(EmailJobKeys.Port, 587); // 465端口一直尝试不通过,奇怪
dataMap.Put(EmailJobKeys.UserName, "390915549@qq.com"); // 作者qq,欢迎骚扰
dataMap.Put(EmailJobKeys.Password, "cirxjtemuzxycagf");
dataMap.Put(EmailJobKeys.To, string.Empty); // 接收者邮件支持多个,以 ; 隔开
dataMap.Put(EmailJobKeys.NickName, "Quartz.NET任务调度通知");
dataMap.Put(EmailJobKeys.CacheExpiry, 30); // 默认30分钟内只通知一次
IJobDetail job = JobBuilder.Create<HttpJob>()
.StoreDurably(true)
.RequestRecovery()
.WithDescription("邮件通知配置Job,切勿删除")
.WithIdentity(key)
.UsingJobData(dataMap)
.Build();
scheduler.AddJob(job, true); // 初始化邮件通知配置
} IJobDetail emailJob = scheduler.GetJobDetail(key).Result;
IFluentEmail fluentEmail = new Email(new ReplaceRenderer(),
new SmtpSender(new SmtpClient(emailJob.JobDataMap.GetString(EmailJobKeys.Host), emailJob.JobDataMap.GetInt(EmailJobKeys.Port))
{
EnableSsl = true,
Credentials = new NetworkCredential(emailJob.JobDataMap.GetString(EmailJobKeys.UserName),
emailJob.JobDataMap.GetString(EmailJobKeys.Password))
}),
emailJob.JobDataMap.GetString(EmailJobKeys.UserName),
emailJob.JobDataMap.GetString(EmailJobKeys.NickName));
return fluentEmail;
}); IocEngine.Instance.Init(services); // 实在没办法才弄个静态容器获取service, 监听器里无法通过构造函数 注入 ISchedulerFactory, IFluentEmail, 猜测应该是循环引用了
}

5、谢谢观看,拜拜
基于Asp.Net Core 5.0依赖Quartz.Net框架编写的任务调度web管理平台的更多相关文章
- 用VSCode开发一个基于asp.net core 2.0/sql server linux(docker)/ng5/bs4的项目(1)
最近使用vscode比较多. 学习了一下如何在mac上使用vscode开发asp.netcore项目. 这里是我写的关于vscode的一篇文章: https://www.cnblogs.com/cgz ...
- [译]基于ASP.NET Core 3.0的ABP v0.21已发布
基于ASP.NET Core 3.0的ABP v0.21已发布 在微软发布仅仅一个小时后, 基于ASP.NET Core 3.0的ABP v0.21也紧跟着发布了. v0.21没有新功能.它只是升级到 ...
- Asp.Net Core 2.0 项目实战(3)NCMVC角色权限管理前端UI预览及下载
Asp.Net Core 2.0 项目实战(1) NCMVC开源下载了 Asp.Net Core 2.0 项目实战(2)NCMVC一个基于Net Core2.0搭建的角色权限管理开发框架 Asp.Ne ...
- 基于ASP.NET Core 3.0快速搭建Razor Pages Web应用
前言 虽然说学习新的开发框架是一项巨大的投资,但是作为一个开发人员,不断学习新的技术并快速上手是我们应该掌握的技能,甚至是一个.NET Framework开发人员,学习.NET Core 新框架可以更 ...
- 基于ASP.NET Core 6.0的整洁架构
大家好,我是张飞洪,感谢您的阅读,我会不定期和你分享学习心得,希望我的文章能成为你成长路上的垫脚石,让我们一起精进. 本节将介绍基于ASP.NET Core的整洁架构的设计理念,同时基于理论落地的代码 ...
- 打造静态分析器(二)基于Asp.Net Core 3.0的AspectCore组件检测
上一篇,我们打造了一个简单的分析器,但是我们实际使用分析器就是为了对项目做分析检测,增加一些非语法的自检的 比如Asp.Net Core 3.0的替换依赖注入检测 设计分析 我们创建一个默认的Asp. ...
- 用VSCode开发一个基于asp.net core 2.0/sql server linux(docker)/ng5/bs4的项目(2)
第一部分: http://www.cnblogs.com/cgzl/p/8478993.html 为Domain Model添加约束 前一部分, 我们已经把数据库创建出来了. 那么我们先看看这个数据库 ...
- [译]ASP.NET Core 2.0 依赖注入
问题 如何使用 ASP.NET Core 服务容器进行依赖注入? 答案 创建一个服务 public interface IGreetingService { string Greet(string t ...
- 基于ASP.Net Core开发一套通用后台框架记录-(项目的搭建)
写在前面 本系列博客是本人在学习的过程中搭建学习的记录,如果对你有所帮助那再好不过.如果您有发现错误,请告知我,我会第一时间修改. 前期我不会公开源码,我想是一点点敲代码,不然复制.粘贴那就没意思了. ...
随机推荐
- (转) SQL 中的 NULL 你真的懂了吗?【数据库|SQL】
注:转载自下面链接 https://blog.csdn.net/lnotime/article/details/104847946 SQL 中的 NULL (译自 NULL Values in SQL ...
- VMware提示Device/Credential Guard不兼容
问题环境 win10系统版本 win10 2004企业版 vmware 版本 vmware 15 pro 问题 虚拟机开启时候弹窗提示:"VMware与Device/Credential G ...
- 图的建立以及应用(BFS,DFS,Prim)
关于带权无向图的一些操作 题目:根据图来建立它的邻接矩阵,通过邻接矩阵转化为邻接表,对邻接表进行深度优先访问和广度优先访问,最后用邻接矩阵生成它的最小生成树: 1.输入一个带权无向图(如下面图1和图2 ...
- VMware虚拟机安装Win7填坑
今天本想赶紧安装Win7虚拟机做个实验,结果鼓捣了一天,写个文章填下坑. 一.Win7镜像文件下载 下载ISO镜像地址:http://msdn.itellyou.cn/ 二.安装tools VMwar ...
- 浅析Linux 64位系统虚拟地址和物理地址的映射及验证方法
虚拟内存 先简单介绍一下操作系统中为什么会有虚拟地址和物理地址的区别.因为Linux中有进程的概念,那么每个进程都有自己的独立的地址空间. 现在的操作系统都是64bit的,也就是说如果在用户态的进程中 ...
- DateUtils 时间工具类
首先,定义`时间枚举值` public enum TimeEnum { /** * 时间格式 */ YYYY_MM_DD("yyyy-MM-dd"), YYYY_MM_DD_HH_ ...
- C#中搜索xsd文件中的某个数据源
步骤 1.打开***.xsd文件. 2.数据源之间的空白处,右键->属性. 3.在VS右侧会跳出一个属性窗口. 4.有个名称为DataSet的下拉框,所有的数据源名称都在其中,单击即可定位到所选 ...
- webform中配置服务器控件的样式
前台 Style <asp:Label ID="Label1" runat="server" Text="Label" Style=& ...
- Java学习_反射
什么是反射? 反射就是Reflection,Java的反射是指程序在运行期可以拿到一个对象的所有信息. 反射是为了解决在运行期,对某个实例一无所知的情况下,如何调用其方法. JAVA反射机制是在运行状 ...
- Java连接MySQL数据库——含详细步骤和代码
工具:eclipse.MySQL.MySQL连接驱动:mysql-connector-java-5.1.45.jar 首先要下载Connector/J地址:http://www.mysql.com/d ...