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來實現,我設計一個定時器,隔幾分鍾就執行以下任務,不管成功不成功,都得執行。

  但是你得注意,這個執行是重新執行的意思,所以假若你想實現發送郵件,放置一直重復發送,你可以用一張表記錄發送到哪里了,放置一直在發送。任務沒有實現記錄任務狀態,后面也許我會改進改進,讓這個任務管理記住狀態,但是我覺得很難抽象出所有的任務類型。

  


免責聲明!

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



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