zoukankan      html  css  js  c++  java
  • CJCMS系列说说项目中的任务管理模式

      在系统开发过程中,肯定会有许多比较大型的任务需要去做,例如给所有注册的用户发送推广邮件,可是要是注册用户达到几十万级别,那我想这个发送邮件的工作可能真的让你很头疼,几十万的发送量,根本无法保证发送过程不会出错,被应用程序池回收,毕竟占得内存太大了,或者耗时过长。那任务管理不得不提上来讲讲了。

      任务管理,最重要的就是保证任务能够完整的完成,不管遇到什么问题,是否线程崩溃或被回收。

      就拿你要发邮件做例子,这么多的邮件,我想不可能一次就发完的,那我们就隔几分钟发送1000人也好啊。

      下面是代码:

      

     1 /******************************************************************
     2 * 作者:                    不要理我 CJ
     3 * 邮件:               869722304@qq.com(仅仅支持商业合作洽谈)
     4 * 创建时间:                2012-8-16 20:12:38
     5 * 最后修改时间:            2012-8-16 20:12:38
     6 * 
     7 * 未经修改的文件版权属于原作者所有,但是你可以阅读,修改,调试。本项目不建议商用,不能确保稳定性。
     8 * 同时由于项目bug引起的一切问题,原作者概不负责。
     9 *
    10 * 本项目所引用的所有类库,仍然遵循其原本的协议,不得侵害其版权。
    11 *
    12 * 您一旦下载就视为您已经阅读此声明。
    13 *
    14 * 您不可以移除项目中的任何声明。
    15 *******************************************************************/
    16 using System;
    17 using System.Collections.Generic;
    18 using System.Linq;
    19 using System.Text;
    20 
    21 namespace CJCMS.Framework.Task
    22 {
    23     public interface IBackgroundTask
    24     {
    25         bool IsWorking { get; set; }
    26         void DoWork();
    27     }
    28 }
     1 /******************************************************************
     2 * 作者:                    不要理我 CJ
     3 * 邮件:               869722304@qq.com(仅仅支持商业合作洽谈)
     4 * 创建时间:                2012-8-16 21:17:01
     5 * 最后修改时间:            2012-8-16 21:17:01
     6 * 
     7 * 未经修改的文件版权属于原作者所有,但是你可以阅读,修改,调试。本项目不建议商用,不能确保稳定性。
     8 * 同时由于项目bug引起的一切问题,原作者概不负责。
     9 *
    10 * 本项目所引用的所有类库,仍然遵循其原本的协议,不得侵害其版权。
    11 *
    12 * 您一旦下载就视为您已经阅读此声明。
    13 *
    14 * 您不可以移除项目中的任何声明。
    15 *******************************************************************/
    16 
    17 using System;
    18 using System.Collections.Generic;
    19 using System.Linq;
    20 using System.Text;
    21 
    22 namespace CJCMS.Framework.Task
    23 {
    24     public class DefaultBackgroundTask:IBackgroundTask
    25     {
    26         public bool IsWorking { get; set; }
    27 
    28         public DefaultBackgroundTask()
    29         {
    30             IsWorking = true;
    31         }
    32 
    33         public int k = 0;
    34         public void DoWork()
    35         {
    36             k += 1;//当然这里实现发邮件也是可以的。
    37         }
    38     }
    39 }
     1 /******************************************************************
     2 * 作者:                    不要理我 CJ
     3 * 邮件:               869722304@qq.com(仅仅支持商业合作洽谈)
     4 * 创建时间:                2012-8-16 20:14:04
     5 * 最后修改时间:            2012-8-16 20:14:04
     6 * 
     7 * 未经修改的文件版权属于原作者所有,但是你可以阅读,修改,调试。本项目不建议商用,不能确保稳定性。
     8 * 同时由于项目bug引起的一切问题,原作者概不负责。
     9 *
    10 * 本项目所引用的所有类库,仍然遵循其原本的协议,不得侵害其版权。
    11 *
    12 * 您一旦下载就视为您已经阅读此声明。
    13 *
    14 * 您不可以移除项目中的任何声明。
    15 *******************************************************************/
    16 using System;
    17 using System.Collections.Generic;
    18 using System.Linq;
    19 using System.Text;
    20 using System.Timers;
    21 
    22 namespace CJCMS.Framework.Task
    23 {
    24     public interface IBackgroundTaskManager
    25     {
    26         Timer _timer { get; set; }
    27         void Elapsed(object sender, ElapsedEventArgs e);
    28     }
    29 }
      1 /******************************************************************
      2 * 作者:                    不要理我 CJ
      3 * 邮件:               869722304@qq.com(仅仅支持商业合作洽谈)
      4 * 创建时间:                2012-8-16 20:52:35
      5 * 最后修改时间:            2012-8-16 20:52:35
      6 * 
      7 * 未经修改的文件版权属于原作者所有,但是你可以阅读,修改,调试。本项目不建议商用,不能确保稳定性。
      8 * 同时由于项目bug引起的一切问题,原作者概不负责。
      9 *
     10 * 本项目所引用的所有类库,仍然遵循其原本的协议,不得侵害其版权。
     11 *
     12 * 您一旦下载就视为您已经阅读此声明。
     13 *
     14 * 您不可以移除项目中的任何声明。
     15 *******************************************************************/
     16 
     17 using System;
     18 using System.Collections.Generic;
     19 using System.Linq;
     20 using System.Text;
     21 using System.Timers;
     22 
     23 namespace CJCMS.Framework.Task
     24 {
     25     public class DefaultBackgroundTaskManager:IBackgroundTaskManager
     26     {
     27         public Timer _timer { get; set; }
     28         private static Dictionary<string, IBackgroundTask> _entries = new Dictionary<string, IBackgroundTask>();
     29 
     30         public TimeSpan Interval
     31         {
     32             get { return TimeSpan.FromMilliseconds(_timer.Interval); }
     33             set { _timer.Interval = value.TotalMilliseconds; }
     34         }
     35 
     36         public DefaultBackgroundTaskManager(double min)
     37         {
     38             _timer = new Timer();
     39             Interval = TimeSpan.FromMinutes(min);
     40             _timer.Elapsed += Elapsed;
     41             _timer.Start();
     42         }
     43 
     44         public void Elapsed(object sender, ElapsedEventArgs e)
     45         {
     46             if (!System.Threading.Monitor.TryEnter(_timer))
     47                 return;
     48 
     49             try
     50             {
     51                 if (_timer.Enabled)
     52                 {
     53                     foreach (KeyValuePair<string, IBackgroundTask> k in _entries.ToList())
     54                     {
     55                         if (k.Value.IsWorking)
     56                         {
     57                             k.Value.DoWork();
     58                         }
     59                         else
     60                         {
     61                             Remove(k.Key);
     62                         }
     63                     }
     64                 }
     65             }
     66             catch (Exception ex)
     67             {
     68                
     69             }
     70             finally
     71             {
     72                 System.Threading.Monitor.Exit(_timer);
     73             }
     74             
     75         }
     76 
     77         ~DefaultBackgroundTaskManager()
     78         {
     79             _timer.Stop();
     80         }
     81 
     82         private static void Add(string key, IBackgroundTask task)
     83         {
     84             lock (_entries)
     85             {
     86                 _entries.Add(key, task);
     87             }
     88         }
     89 
     90         public static void Remove(string key)
     91         {
     92             lock (_entries)
     93             {
     94                 _entries.Remove(key);
     95             }
     96         }
     97 
     98         public static void TryAdd(string key, IBackgroundTask task)
     99         {
    100             if (_entries.Where(a => a.Key == key).Count() == 0)
    101             {
    102                 Add(key, task);
    103             }
    104         }
    105     }
    106 }

      你看到了,任务管理其实是用了Timer来实现,我设计一个定时器,隔几分钟就执行以下任务,不管成功不成功,都得执行。

      但是你得注意,这个执行是重新执行的意思,所以假若你想实现发送邮件,放置一直重复发送,你可以用一张表记录发送到哪里了,放置一直在发送。任务没有实现记录任务状态,后面也许我会改进改进,让这个任务管理记住状态,但是我觉得很难抽象出所有的任务类型。

      

  • 相关阅读:
    【深入理解Java虚拟机】类加载机制
    【深入理解Java虚拟机】四种引用类型的特点
    【深入理解Java虚拟机】JVM内存区域
    【每日一题】单词搜索
    过滤器和拦截器有啥区别,这次会了!
    Filter过滤器简单入门
    SpringMVC的运行流程+常用注解总结
    SpringAOP+源码解析,切就完事了
    Spring的循环依赖,学就完事了【附源码】
    Markdown的流程图制作
  • 原文地址:https://www.cnblogs.com/ntcj/p/2646673.html
Copyright © 2011-2022 走看看