diff --git a/CronNET.sln b/CronNET.sln old mode 100644 new mode 100755 index 6066190..3d79796 --- a/CronNET.sln +++ b/CronNET.sln @@ -1,6 +1,6 @@  -Microsoft Visual Studio Solution File, Format Version 9.00 -# Visual Studio 2005 +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual C# Express 2010 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CronNET", "CronNET\CronNET.csproj", "{F31D7AF3-FDFA-44F1-9C63-305BAF11D002}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CronNETTests", "CronNETTests\CronNETTests.csproj", "{6FCFBDF4-ECB7-4FC2-A376-E962B11D487D}" diff --git a/CronNET/CronDaemon.cs b/CronNET/CronDaemon.cs old mode 100644 new mode 100755 index 93cd632..fdc0f53 --- a/CronNET/CronDaemon.cs +++ b/CronNET/CronDaemon.cs @@ -1,30 +1,34 @@ using System; using System.Collections.Generic; using System.Timers; +using System.Threading; namespace CronNET { public class CronDaemon { - private readonly Timer timer = new Timer(60000); + private readonly System.Timers.Timer timer = new System.Timers.Timer(30000); private readonly List cron_jobs = new List(); + private DateTime _last= DateTime.Now; public CronDaemon() { + timer.AutoReset = true; timer.Elapsed += timer_elapsed; } - public void add_job(CronJob cron_job) + public void AddJob(string schedule, ThreadStart action) { - cron_jobs.Add(cron_job); + var cj = new CronJob(schedule, action); + cron_jobs.Add(cj); } - public void start() + public void Start() { timer.Start(); } - public void stop() + public void Stop() { timer.Stop(); @@ -34,8 +38,12 @@ namespace CronNET private void timer_elapsed(object sender, ElapsedEventArgs e) { - foreach (CronJob job in cron_jobs) - job.execute(DateTime.Now); + if (DateTime.Now.Minute != _last.Minute) + { + _last = DateTime.Now; + foreach (CronJob job in cron_jobs) + job.execute(DateTime.Now); + } } } } diff --git a/CronNET/CronJob.cs b/CronNET/CronJob.cs old mode 100644 new mode 100755 index 17cb2ec..a98c416 --- a/CronNET/CronJob.cs +++ b/CronNET/CronJob.cs @@ -16,16 +16,20 @@ namespace CronNET _thread = new Thread(thread_start); } + private object _lock = new object(); public void execute(DateTime date_time) { - if (!_cron_schedule.is_time(date_time)) - return; + lock (_lock) + { + if (!_cron_schedule.isTime(date_time)) + return; - if (_thread.ThreadState == ThreadState.Running) - return; + if (_thread.ThreadState == ThreadState.Running) + return; - _thread = new Thread(_thread_start); - _thread.Start(); + _thread = new Thread(_thread_start); + _thread.Start(); + } } public void abort() diff --git a/CronNET/CronNET.csproj b/CronNET/CronNET.csproj old mode 100644 new mode 100755 index ff762de..62d75b3 --- a/CronNET/CronNET.csproj +++ b/CronNET/CronNET.csproj @@ -1,4 +1,5 @@ - + + Debug AnyCPU @@ -9,6 +10,12 @@ Properties Cron Cron + v4.0 + + + + + 2.0 true diff --git a/CronNET/CronSchedule.cs b/CronNET/CronSchedule.cs old mode 100644 new mode 100755 index 880d839..23ddc6f --- a/CronNET/CronSchedule.cs +++ b/CronNET/CronSchedule.cs @@ -9,7 +9,7 @@ namespace CronNET #region Readonly Class Members readonly static Regex divided_regex = new Regex(@"(\*/\d+)"); - readonly static Regex range_regex = new Regex(@"(\d+\-\d+)"); + readonly static Regex range_regex = new Regex(@"(\d+\-\d+)\/?(\d+)?"); readonly static Regex wild_regex = new Regex(@"(\*)"); readonly static Regex list_regex = new Regex(@"(((\d+,)*\d+)+)"); readonly static Regex validation_regex = new Regex(divided_regex + "|" + range_regex + "|" + wild_regex + "|" + list_regex); @@ -17,9 +17,9 @@ namespace CronNET #endregion #region Private Instance Members - + private readonly string _expression; - public List minutes; + public List minutes; public List hours; public List days_of_month; public List months; @@ -43,65 +43,81 @@ namespace CronNET #region Public Methods - public bool is_valid() + private bool isValid() { - return is_valid(this._expression); + return isValid(this._expression); } - public bool is_valid(string expression) - { - MatchCollection matches = validation_regex.Matches(expression); - return matches.Count == 5; + public bool isValid(string expression) + { + MatchCollection matches = validation_regex.Matches(expression); + return matches.Count > 0;//== 5; } - public bool is_time(DateTime date_time) + public bool isTime(DateTime date_time) { return minutes.Contains(date_time.Minute) && - hours.Contains(date_time.Hour) && + hours.Contains(date_time.Hour) && days_of_month.Contains(date_time.Day) && months.Contains(date_time.Month) && days_of_week.Contains((int)date_time.DayOfWeek); } - public void generate() + private void generate() { - if(!is_valid()) return; + if (!isValid()) return; - MatchCollection matches = validation_regex.Matches(this._expression); + MatchCollection matches = validation_regex.Matches(this._expression); - generate_minutes(matches[0]); - generate_hours(matches[1]); - generate_days_of_month(matches[2]); - generate_months(matches[3]); - generate_days_of_weeks(matches[4]); + generate_minutes(matches[0].ToString()); + + if (matches.Count > 1) + generate_hours(matches[1].ToString()); + else + generate_hours("*"); + + if (matches.Count > 2) + generate_days_of_month(matches[2].ToString()); + else + generate_days_of_month("*"); + + if (matches.Count > 3) + generate_months(matches[3].ToString()); + else + generate_months("*"); + + if (matches.Count > 4) + generate_days_of_weeks(matches[4].ToString()); + else + generate_days_of_weeks("*"); } - public void generate_minutes(Match match) + private void generate_minutes(string match) { - this.minutes = generate_values(match.ToString(), 0, 60); + this.minutes = generate_values(match, 0, 60); } - public void generate_hours(Match match) + private void generate_hours(string match) { - this.hours = generate_values(match.ToString(), 0, 24); + this.hours = generate_values(match, 0, 24); } - public void generate_days_of_month(Match match) + private void generate_days_of_month(string match) { - this.days_of_month = generate_values(match.ToString(), 1, 32); + this.days_of_month = generate_values(match, 1, 32); } - public void generate_months(Match match) + private void generate_months(string match) { - this.months = generate_values(match.ToString(), 1, 13); + this.months = generate_values(match, 1, 13); } - public void generate_days_of_weeks(Match match) + private void generate_days_of_weeks(string match) { - this.days_of_week = generate_values(match.ToString(), 0, 7); + this.days_of_week = generate_values(match, 0, 7); } - public List generate_values(string configuration, int start, int max) + private List generate_values(string configuration, int start, int max) { if (divided_regex.IsMatch(configuration)) return divided_array(configuration, start, max); if (range_regex.IsMatch(configuration)) return range_array(configuration); @@ -111,31 +127,44 @@ namespace CronNET return new List(); } - public List divided_array(string configuration, int start, int max) + private List divided_array(string configuration, int start, int max) { - if(!divided_regex.IsMatch(configuration)) + if (!divided_regex.IsMatch(configuration)) return new List(); List ret = new List(); string[] split = configuration.Split("/".ToCharArray()); int divisor = int.Parse(split[1]); - for(int i=start; i < max; ++i) - if(i % divisor == 0) - ret.Add(i); + for (int i = start; i < max; ++i) + if (i % divisor == 0) + ret.Add(i); return ret; } - public List range_array(string configuration) + private List range_array(string configuration) { - if(!range_regex.IsMatch(configuration)) + if (!range_regex.IsMatch(configuration)) return new List(); List ret = new List(); string[] split = configuration.Split("-".ToCharArray()); int start = int.Parse(split[0]); - int end = int.Parse(split[1]); + int end = 0; + if (split[1].Contains("/")) + { + split = split[1].Split("/".ToCharArray()); + end = int.Parse(split[0]); + int divisor = int.Parse(split[1]); + + for (int i = start; i < end; ++i) + if (i % divisor == 0) + ret.Add(i); + return ret; + } + else + end = int.Parse(split[1]); for (int i = start; i <= end; ++i) ret.Add(i); @@ -143,9 +172,9 @@ namespace CronNET return ret; } - public List wild_array(string configuration, int start, int max) + private List wild_array(string configuration, int start, int max) { - if(!wild_regex.IsMatch(configuration)) + if (!wild_regex.IsMatch(configuration)) return new List(); List ret = new List(); @@ -156,16 +185,16 @@ namespace CronNET return ret; } - public List list_array(string configuration) + private List list_array(string configuration) { - if(!list_regex.IsMatch(configuration)) + if (!list_regex.IsMatch(configuration)) return new List(); List ret = new List(); string[] split = configuration.Split(",".ToCharArray()); - foreach(string s in split) + foreach (string s in split) ret.Add(int.Parse(s)); return ret; diff --git a/CronNET/Properties/AssemblyInfo.cs b/CronNET/Properties/AssemblyInfo.cs old mode 100644 new mode 100755 diff --git a/CronNETTests/CronNETTests.csproj b/CronNETTests/CronNETTests.csproj old mode 100644 new mode 100755 index b35342a..f7b9711 --- a/CronNETTests/CronNETTests.csproj +++ b/CronNETTests/CronNETTests.csproj @@ -1,4 +1,5 @@ - + + Debug AnyCPU @@ -9,6 +10,27 @@ Properties CronTests CronTests + v4.0 + + + + + 2.0 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true true @@ -28,7 +50,10 @@ 4 - + + False + C:\Program Files (x86)\NUnit 2.5.10\bin\net-2.0\framework\nunit.framework.dll + @@ -43,6 +68,28 @@ CronNET + + + False + Microsoft .NET Framework 4 %28x86 and x64%29 + true + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + false + + + False + Windows Installer 3.1 + true + +