在吉日嘎拉DotNet.WebForm中使用FluentScheduler调度任务
有些用户一直说系统发送的邮件一直收不到,投诉系统不正常,这时候怎么洗刷冤屈呢?将发送的每一封Email都保存到数据库中,并记录发送的日志,让用户无话可说。
自己创建3个表:
- MessageFailed - 失败记录(超过5次发送失败就保存到这里)
- MessageQueue - 信息队列 (成功了就放MessageSucceed,失败5次就保存到MessageFailed)
- MessageSucceed - 成功记录
使用FluentScheduler,直接在Web端调度,省去Windows服务程序。

FluentScheduler
Automated job scheduler with fluent interface.
相关代码,我是用了IRegisteredObject,避免Application Pool和进程重启造成的Job中断等异常:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web; namespace DotNet.Business
{
using DotNet.Model;
using DotNet.Business;
using DotNet.Utilities; using FluentScheduler;
using System.Web.Hosting; #region MessageRegistry
public partial class MessageRegistry : Registry
{
public MessageRegistry()
{
//不允许重复进入
NonReentrantAsDefault(); // Schedule an IJob to run at an interval
Schedule<MessageJob>().NonReentrant().ToRunNow().AndEvery().Seconds(); //// Schedule an IJob to run once, delayed by a specific time interval
//Schedule<MessageJob>().ToRunOnceIn(5).Seconds(); //// Schedule a simple job to run at a specific time
//Schedule(() => Console.WriteLine("It's 9:15 PM now.")).ToRunEvery(1).Days().At(21, 15); //// Schedule a more complex action to run immediately and on an monthly interval
//Schedule<MessageJob>().ToRunNow().AndEvery(1).Months().OnTheFirst(DayOfWeek.Monday).At(3, 0); //// Schedule multiple jobs to be run in a single schedule
//Schedule<MessageJob>().AndThen<MessageJob>().ToRunNow().AndEvery(5).Minutes();
}
}
#endregion #region MessageJob
public partial class MessageJob : BaseManager, IBaseManager, IJob, IRegisteredObject
{
private readonly object _lock = new object(); private bool _shuttingDown; public MessageJob()
{
//Register this job with the hosting environment.
//Allows for a more graceful stop of the job, in the case of IIS shutting down.
HostingEnvironment.RegisterObject(this);
} public void Execute()
{
lock (_lock)
{
if (_shuttingDown)
return; //Do work, son!
new MessageQueueManager(this.UserInfo).Resend();
}
} public void Stop(bool immediate)
{
//Locking here will wait for the lock in Execute to be released until this code can continue.
lock (_lock)
{
_shuttingDown = true;
} HostingEnvironment.UnregisterObject(this);
} }
#endregion
}
调度的时候,在Global.asax中调度如下:
//FluentScheduler任务调度
FluentScheduler.JobManager.Initialize(new DotNet.Business.MessageRegistry());
Message相关的代码,MessageFailed中的邮件发送Error的记录暂未实现:
#region 重新发送消息
/// <summary>
/// 重新发送消息
/// </summary>
/// <param name="id">主键</param>
/// <returns>是否成功</returns>
public bool Resend(MessageQueueEntity entity, int maxFailCount = )
{
bool result = false;
if (entity.MessageType.ToLower().Contains("mail"))
{
if (MailUtil.Send(entity.Recipient, entity.Subject, entity.Body))
{
//发送成功,移动数据到MessageSucceed表
MessageSucceedEntity entitySuccesed = new MessageSucceedEntity();
entitySuccesed.MessageType = entity.MessageType;
entitySuccesed.Recipient = entity.Recipient;
entitySuccesed.Subject = entity.Subject;
entitySuccesed.Body = entity.Body;
entitySuccesed.CreateOn = entity.CreateOn;
new MessageSucceedManager(this.UserInfo).Add(entitySuccesed);
//删除MessageQueue表中的数据
//this.Delete(entity.Id);
this.DeleteObject(entity.Id);
result = true;
}
else
{
//更新MessageQueue表中的失败次数
entity.FailCount = entity.FailCount + ;
this.UpdateObject(entity);
if (entity.FailCount >= maxFailCount)
{
//发送失败超过5次,移动数据到MessageFailed表
MessageFailedEntity entityFailed = new MessageFailedEntity();
entityFailed.MessageType = entity.MessageType;
entityFailed.Recipient = entity.Recipient;
entityFailed.Subject = entity.Subject;
entityFailed.Body = entity.Body;
entityFailed.FailCount = entity.FailCount;
entityFailed.CreateOn = entity.CreateOn;
//entityFailed.Error = "";
new MessageFailedManager(this.UserInfo).Add(entityFailed);
//删除MessageQueue表中的数据
//this.Delete(entity.Id);
this.DeleteObject(entity.Id);
result = false;
}
result = false;
} }
return result;
}
#endregion #region 重新发送所有队列
/// <summary>
/// 重新发送所有队列
/// </summary>
/// <returns>发送成功数量</returns>
public int Resend(int maxFailCount = )
{
int result = ;
//每次发一封,避免超时,任务不停启动而listEntity并未重新获取
List<MessageQueueEntity> listEntity = this.GetList<MessageQueueEntity>(, MessageQueueEntity.FieldId);
foreach (var entity in listEntity)
{
if (this.Resend(entity, maxFailCount))
{
result++;
}
} return result;
}
#endregion
因为这个后台Job的调度是邮件发送,其实MVC的项目也可以直接用上述代码。
在吉日嘎拉DotNet.WebForm中使用FluentScheduler调度任务的更多相关文章
- 吉日嘎拉DotNet.BusinessV4.2中的一处bug,及我的修复和扩展
bug所在位置:DotNet.Business\Utilities\BaseManager.GetDataTableByPage.cs的函数 public virtual DataTable GetD ...
- C#开发中Windows域认证登录2(扩展吉日嘎拉GPM系统)
原文地址:http://www.cuiwenyuan.com/shanghai/post/Windows-AD-Logon-Intergrated-into-Jirigala-GPM-DotNet-B ...
- C#开发中Windows域认证登录2016(扩展吉日嘎拉GPM系统V4.2)
2013年搞公司的OA时,为了统一用户登录,将Windows AD的用户和OA的账号对接,OA用户名的规则就是使用Windows AD的用户名,格式举例:Troy.Cui,原理就是先进行域服务器的认证 ...
- 基于吉日嘎拉的通用权限管理Webform版老界面bug修复
虽然弄了新界面<基于吉日嘎底层架构的通用权限管理Web端UI更新:参考DTcms后台界面>,但老界面的一点菜单显示的问题还是让我这种强迫症揪心,终于今晚可以美美的睡觉了. 老代码用了Ses ...
- 吉日嘎拉C#快速开发平台V4.0到V4.2升级记
目前我用的版本是4.0的,也有近2年没更新了,狠了狠心升级一下,没想到真的行动起来,也没那么难! 用了3天时间,将吉日嘎拉的代码升级到了4.2版本,并让原来的DotNet.WebApplication ...
- webform 中使用ajax
常用的方式有 js –> WebService , js->*.ashx, js->WebAPI, js->MVC Controller->Action. 前两种就不说 ...
- 基于吉日嘎拉的OA协同办公模块重写
这一个月的业余时间主要是在忙这个重构的事情,将吉日嘎拉自带的文档管理.公司公告.留言板.通讯录.周任务.考勤,全部重新建表,重构代码和UI. 目前根据中小企业常用的日常办公需要,搞定了公告栏.任务中心 ...
- webform中使用webapi,并且使用autofac
private void AutofacIoCRegister() { HttpConfiguration config = GlobalConfiguration.Configuration; if ...
- 【Ext.Net学习笔记】01:在ASP.NET WebForm中使用Ext.Net
Ext.NET是基于跨浏览器的ExtJS库和.NET Framework的一套支持ASP.NET AJAX的开源Web控件,包含有丰富的Ajax运用,其前身是Coolite. 下载地址:http:// ...
随机推荐
- CSS3动画:YouTube的红色激光进度条
本文只是讨论和实现了动画效果,并未将动画与页面实际下载关联,有朋友们问如何应用,可以使用现成的一些插件比如这个,这个,还有这个. 之前一篇文章<CSS3 动画一瞥>简单介绍了CSS3动画相 ...
- 知方可补不足~sqlserver中使用sp_who查看sql的进程
回到目录 在SQLSERVER中每个会话,即每个查询分析器窗口都会产生一个SQL进程,对于那些持续时间短的进程,它们转瞬即失,而对于持续时间比较长的,我们需要希望查看它的运行状态,就可以借助SQL提供 ...
- Atitit数据库层次架构表与知识点 attilax 总结
Atitit数据库层次架构表与知识点 attilax 总结 第一阶段,大概理论(三五天 数据库的类型,网状,层次,树形数据库,kv数据库.Oodb Er模型 sql 并发控制与lock Acid ...
- react2 react 遍历数组
<body><!-- React 真实 DOM 将会插入到这里 --><div id="example"></div> <!- ...
- 阿里云 云解析使用方法/在阿里云ESC服务器解析域名并绑定服务器IP后上传文件通过域名访问步骤教程
第一步:登录阿里云官网,获取服务器ECS的指定公网IP地址. 1.输入阿里云官网账号进入首页,如下图: 2.点击进入"管理控制台",如下图: 3.点击"云服务器ECS&q ...
- 12.创建一个Point类,有成员变量x,y,方法getX(),setX(),还有一个构造方 法初始化x和y。创建类主类A来测试它。
package java1; public class Point { int x; int y; Point(int x,int y) { this.x = x; this.y = y; } pub ...
- 使用SQL Server Audit记录数据库变更
最近工作中有一个需求,就是某一个比较重要的业务表经常被莫名其妙的变更.在SQL Server中这类工作如果不事前捕获记录的话,无法做到.对于捕获变更来说,可以考虑的选择包括Trace,CDC. ...
- Android开发实践:编译VLC-for-android
最近在Android做流媒体相关的开发,一直想学习一下强大的VLC,正好趁此机会研究研究VLC-for-android的代码,看看优秀的开源音视频播放器是如何实现的.本文总结下在Linux平台下如何编 ...
- 微信开发 -- 搭建基于ngrok的微信本地调试环境
第一步,安装ngrok客户端 (1)首先先到官网下载个客户端 http://natapp.cn/,选择适合的客户端类型,本人选择的是windows版 (2)下载后,解压,可以看到如下目录: 第二步,开 ...
- MySQL PXC 高可用集群搭建
一些名词介绍: WS:write set 写数据集 IST: Incremental State Transfer 增量同步 SST:State Snapshot Transfer 全量同 ...