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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM