• 在吉日嘎拉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的项目也可以直接用上述代码。

  • 相关阅读:
    100LS练习方法
    甲方开源项目
    linux端口转发方式
    内网的一些穿透工具
    Checkpoint防火墙(一)
    2020目标
    Linux逻辑卷的扩容和缩小
    linux挂载磁盘
    Selinux介绍
    以太坊私链搭建
  • 原文地址:https://www.cnblogs.com/cuiwenyuan/p/6200443.html
Copyright © 2020-2023  润新知