CJCMS系列说说项目中的任务管理模式
在系统开发过程中,肯定会有许多比较大型的任务需要去做,例如给所有注册的用户发送推广邮件,可是要是注册用户达到几十万级别,那我想这个发送邮件的工作可能真的让你很头疼,几十万的发送量,根本无法保证发送过程不会出错,被应用程序池回收,毕竟占得内存太大了,或者耗时过长。那任务管理不得不提上来讲讲了。
任务管理,最重要的就是保证任务能够完整的完成,不管遇到什么问题,是否线程崩溃或被回收。
就拿你要发邮件做例子,这么多的邮件,我想不可能一次就发完的,那我们就隔几分钟发送1000人也好啊。
下面是代码:
1 /* *****************************************************************
2 * 作者: 不要理我 CJ
3 * 邮件: 869722304@qq测试数据(仅仅支持商业合作洽谈)
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测试数据(仅仅支持商业合作洽谈)
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测试数据(仅仅支持商业合作洽谈)
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测试数据(仅仅支持商业合作洽谈)
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来实现,我设计一个定时器,隔几分钟就执行以下任务,不管成功不成功,都得执行。
但是你得注意,这个执行是重新执行的意思,所以假若你想实现发送邮件,放置一直重复发送,你可以用一张表记录发送到哪里了,放置一直在发送。任务没有实现记录任务状态,后面也许我会改进改进,让这个任务管理记住状态,但是我觉得很难抽象出所有的任务类型。
前面写了比较多的基础知识,简单来说就是项目的帮助类库吧,下面我就开始写现在比较火的电子商务作为实践的例子,让大家对于我这个架构的赤裸裸的理解,共同进步。
首先,都是前言了。
这次电子商务项目实战呢,我个人对于自己前端的水平真的是不自信,因为只会抄抄别人的东西。所以我大部分的内容都会讲如何通过DDD的思想来构建这样一个系统出来,前端的效果,要是大家有什么比较好用的现成的架构可以推荐给我,同时在开发过程中,我有可能会对之前的项目结构进行重构,毕竟能力有限,请大家批评指正。
先大体上分析一下,电子商务的一些主要的需求。电子商务主要就是商品,商品属性,购物车,订单,订单状态切换,收货地址,用户。
下面是一张我从网络上搜索过来的电子商务的功能结构图,可以说这张图功能真的够了。 这里是原文链接
上面真的把基本上的功能都涵盖了,看到这张图,我觉得我后面的工作还有很多。好了,今天就说这些了。
标签: DDD , 架构设计 , CJCMS , 任务管理
作者: Leo_wl
出处: http://HdhCmsTestcnblogs测试数据/Leo_wl/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
版权信息查看更多关于CJCMS系列说说项目中的任务管理模式的详细内容...