在吉日嘎拉DotNet.WebForm中使用FluentScheduler调度任务

有些用户一直说系统发送的邮件一直收不到,投诉系统不正常,这时候怎么洗刷冤屈呢?将发送的每一封Email都保存到数据库中,并记录发送的日志,让用户无话可说。

自己创建3个表:

  1. MessageFailed - 失败记录(超过5次发送失败就保存到这里)
  2. MessageQueue - 信息队列 (成功了就放MessageSucceed,失败5次就保存到MessageFailed)
  3. 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(1).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 = 5)
        {
            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 + 1;
                    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 = 5)
        {
            int result = 0;
            //每次发一封,避免超时,任务不停启动而listEntity并未重新获取
            List<MessageQueueEntity> listEntity = this.GetList<MessageQueueEntity>(1, MessageQueueEntity.FieldId);
            foreach (var entity in listEntity)
            {
                if (this.Resend(entity, maxFailCount))
                {
                    result++;
                }
            }

            return result;
        }
        #endregion

因为这个后台Job的调度是邮件发送,其实MVC的项目也可以直接用上述代码。

时间: 2024-10-12 22:47:04

在吉日嘎拉DotNet.WebForm中使用FluentScheduler调度任务的相关文章

C#开发中Windows域认证登录2016(扩展吉日嘎拉GPM系统V4.2)

2013年搞公司的OA时,为了统一用户登录,将Windows AD的用户和OA的账号对接,OA用户名的规则就是使用Windows AD的用户名,格式举例:Troy.Cui,原理就是先进行域服务器的认证,认证完毕使用自定义的函数根据用户名读取出OA的用户信息,然后读取出用户名和密码信息,最后使用获取到的用户名和密码进行正常的登录.当时的文章:<C#开发中Windows域认证登录2(扩展吉日嘎拉GPM系统)>,本周打算OA中开发在线培训的功能,也想借此机会升级一下底层的应用DotNet.Busin

吉日嘎拉C#快速开发平台V4.0到V4.2升级记

目前我用的版本是4.0的,也有近2年没更新了,狠了狠心升级一下,没想到真的行动起来,也没那么难! 用了3天时间,将吉日嘎拉的代码升级到了4.2版本,并让原来的DotNet.WebApplication正常运行起来,比料想的顺利.这里简单记录一下升级中的心得. 使用到的工具: 1.BeyondCompare 试用版 - 比较程序文件 2.SQLDelta 14天试用版 - 比较数据库表结构变化(及数据变化) 3.VS2010 - 保证升级后WebApplication好用 4.MSSQL 2008

扩展吉日嘎拉的用户角色管理,让用户角色编码和名称在一个组织里面唯一

吉日嘎拉的权限管理系统原功能中只是控制用户角色名称唯一,但实际使用中我更需要角色编码唯一不重复! 直接上代码,在Role的Add和Update方法中,增加如下代码: //检查角色Code是否重复 Troy.Cui 2016-08-17 List<KeyValuePair<string, object>> parametersCode = new List<KeyValuePair<string, object>>(); if (!string.IsNullO

【Ext.Net学习笔记】01:在ASP.NET WebForm中使用Ext.Net

Ext.NET是基于跨浏览器的ExtJS库和.NET Framework的一套支持ASP.NET AJAX的开源Web控件,包含有丰富的Ajax运用,其前身是Coolite. 下载地址:http://www.ext.net/download/示例地址:http://examples.ext.net/ 1.首先下载Ext.Net,地址:http://www.ext.net/download/ ,有两种框架选择,选择下载WebForms 当前版本是2.5.1,压缩包里面包含了不同版本,分别用在相应.

Ext.Net学习笔记01:在ASP.NET WebForm中使用Ext.Net

Ext.Net是一个对ExtJS进行封装了的.net控件库,可以在ASP.NET WebForm和MVC中使用.从今天开始记录我的学习笔记,这是第一篇,今天学习了如何在WebForm中使用Ext.Net控件库. 下载Ext.Net 首先要去Ext.Net网站上下载Ext.Net,我先学习的是WebForm版: 当前版本是3.1.0,压缩包里面包含了不同版本,分别用在相应.net版本的程序中. 在项目中引用 要使用Ext.Net,首先创建一个WebForm程序,我们这里使用4.5版. 在引用管理器

ASP.NET WebForm中前台代码如何绑定后台变量

转载自 http://www.cnblogs.com/lerit/archive/2010/10/22/1858007.html 经常会碰到在前台代码中要使用(或绑定)后台代码中变量值的问题.一般有<%= str%>和<%# str %>两种方式,这里简单总结一下.如有错误或异议之处,敬请各位指教. 一方面,这里所讲的前台即通常的.aspx文件,后台指的是与aspx相关联的CodeBehind,文件后缀名为.aspx.cs:另一方面,这里的绑定是指用户发出访问某一页面指令后,服务器

webform中 ajax调用后台方法(非webservice)

后台: public partial class Ajax_ShoppingCart : System.Web.UI.Page { bookdbDataContext bdc = Connect.bookdb(); protected void Page_Load(object sender, EventArgs e) { if(!IsPostBack) { if(Request.Form["method"]!=null) { switch (Request.Form["me

webform中Session和Cookies对象的用法、登录保持

一 .webform中Session和Cookies对象的用法 1.Session: Session:在计算机中,尤其是在网络应用中,称为"会话控制".Session 对象存储特定用户会话所需的属性及配置信息.这样,当用户在应用程序的 Web页之间跳转时,存储在 Session 对象中的变量将不会丢失,而是在整个用户会话中一直存在下去.当用户请求来自应用程序的 Web 页时,如果该 用户还没有会话,则 Web 服务器将自动创建一个 Session 对象.当会话过期或被放弃后,服务器将终

WebForm中使用MVC

http://www.cnblogs.com/encoding/articles/3556046.html ************************************************************* 前言 掐指一算,3年没写博了,好懒的说... 众所周知,MVC现在越来越火了,不懂MVC的程序猿都不好意思说自己是搞网站开发的. 虽然MVC与WebForm各有所长,但是基于种种原因,很多用WebForm开发的网站需要转移到MVC上面来.但是,原有的系统上面有非常非常