在系統開發過程中,肯定會有許多比較大型的任務需要去做,例如給所有注冊的用戶發送推廣郵件,可是要是注冊用戶達到幾十萬級別,那我想這個發送郵件的工作可能真的讓你很頭疼,幾十萬的發送量,根本無法保證發送過程不會出錯,被應用程序池回收,畢竟占得內存太大了,或者耗時過長。那任務管理不得不提上來講講了。
任務管理,最重要的就是保證任務能夠完整的完成,不管遇到什么問題,是否線程崩潰或被回收。
就拿你要發郵件做例子,這么多的郵件,我想不可能一次就發完的,那我們就隔幾分鍾發送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來實現,我設計一個定時器,隔幾分鍾就執行以下任務,不管成功不成功,都得執行。
但是你得注意,這個執行是重新執行的意思,所以假若你想實現發送郵件,放置一直重復發送,你可以用一張表記錄發送到哪里了,放置一直在發送。任務沒有實現記錄任務狀態,后面也許我會改進改進,讓這個任務管理記住狀態,但是我覺得很難抽象出所有的任務類型。
