在吉日嘎拉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:// ...
随机推荐
- 字符串查找String.IndexOf
String.indexOf的模拟实现,没想象中有多么高深的查找算法,就是最普通的遍历查找 思路:先找到第一个相同的字符,然后依次比较后面的字符,若都相等则表示查找成功 /** * 查找字符串patt ...
- Oracle+Jsp分页
分页原理: 从jsp页面传到servlet请求中,可以获得当前点击的页数,第一次进入为首页,通过在servlet中获得的当前页数,并且设计一次性显示的内容数,就是几条信息, 并且从dao层查询到数据库 ...
- win2008 强制删除故障集群配置
在正常删除Cluster 节点之后,再添加节点时,报“节点已经加入群集”,无法加入,注册表信息删除后可正常移除Cluster服务,如下: win2008故障转移群集无法退出节点时 删除注册表中这两个后 ...
- 更新日志 - fir.im Jenkins & Gradle 插件上线
最近 fir.im 工程师们效率爆表,fir.im 实用工具集合又添加了新的成员-- Jenkins & Gradle 插件,让 App 打包上传更加简单快速. fir.im Jenkins ...
- Java Annotation 总结
Annotation 被称为注解,在Java开发中是相当常见的,通过注解,我们可以简化代码提高开发效率.例如Override Annotation,这个应该算是在开发过程中使用最多的注解了.下面这个例 ...
- js算法之最常用的排序
引入 大学学习计算机语言的那几年,从c语言,到c++,再到数据结构JAVA..让我印象最深刻的还是最开始老师讲冒泡算法的时候,直到现在大四快毕业了我才渐渐通窍了.刚学前端的时候以为前端就是做出好看很炫 ...
- SSM环境搭建(接口编程方式)
一直用ssm在开发项目,之前都是直接copy别人的项目,今天趁着项目刚刚交付,自己搭建一下ssm环境,做个记录 一.创建项目.引入jar包,因为版本不一样,就不贴出这部分的内容了.个人平时的习惯是,先 ...
- Design4:数据库设计规范
当数据模型从概念层转到逻辑层时,需要进行规范化设计.要想设计一个结构合理的关系型数据库,至少需要满足1NF,2NF,3NF,即第一范式,第二范式,第三范式. 1,1NF(原子性) 1NF是最基本的,数 ...
- JS性能--DOM编程之重排与重绘
浏览器下载完页面中的所有组件----HTML标记,Js,CSS,图片等之后会解析并生成两个内部数据结构: DOM树 -------- 表示页面结构 渲染树 -------- 表示DOM节点如何显 ...
- Java多线程系列--“JUC集合”03之 CopyOnWriteArraySet
概要 本章是JUC系列中的CopyOnWriteArraySet篇.接下来,会先对CopyOnWriteArraySet进行基本介绍,然后再说明它的原理,接着通过代码去分析,最后通过示例更进一步的了解 ...