diff --git a/Pfr.Services.Scheduler.sln b/Pfr.Services.Scheduler.sln new file mode 100644 index 0000000..95c5de4 --- /dev/null +++ b/Pfr.Services.Scheduler.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.32112.339 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Pfr.Services.Scheduler", "Pfr.Services.Scheduler\Pfr.Services.Scheduler.csproj", "{7D0E3F8D-917D-41CF-B093-A5365C8F24F3}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Pfr.Services.SchedulerTests", "Pfr.Services.SchedulerTests\Pfr.Services.SchedulerTests.csproj", "{02192A90-645F-4DBC-866D-A1E890905C44}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {7D0E3F8D-917D-41CF-B093-A5365C8F24F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7D0E3F8D-917D-41CF-B093-A5365C8F24F3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7D0E3F8D-917D-41CF-B093-A5365C8F24F3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7D0E3F8D-917D-41CF-B093-A5365C8F24F3}.Release|Any CPU.Build.0 = Release|Any CPU + {02192A90-645F-4DBC-866D-A1E890905C44}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {02192A90-645F-4DBC-866D-A1E890905C44}.Debug|Any CPU.Build.0 = Debug|Any CPU + {02192A90-645F-4DBC-866D-A1E890905C44}.Release|Any CPU.ActiveCfg = Release|Any CPU + {02192A90-645F-4DBC-866D-A1E890905C44}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {5079223D-206D-44BE-8FB5-E7AB3657172D} + EndGlobalSection +EndGlobal diff --git a/Pfr.Services.Scheduler/Pfr.Services.Scheduler.csproj b/Pfr.Services.Scheduler/Pfr.Services.Scheduler.csproj new file mode 100644 index 0000000..079c661 --- /dev/null +++ b/Pfr.Services.Scheduler/Pfr.Services.Scheduler.csproj @@ -0,0 +1,11 @@ + + + + net6.0 + enable + enable + True + $(VersionPrefix)1.2.3 + + + diff --git a/Pfr.Services.Scheduler/Scheduler.cs b/Pfr.Services.Scheduler/Scheduler.cs new file mode 100644 index 0000000..92be441 --- /dev/null +++ b/Pfr.Services.Scheduler/Scheduler.cs @@ -0,0 +1,86 @@ +namespace Pfr.Services.Scheduler +{ + public class Scheduler + { + private long _Interval = 1000; + private Timer _timer; + private TimerCallback _timerCallback; + private TimeExec _TimeExec; + private DateTime _DateTimeExec; + + /// + /// + /// + /// + public Scheduler(TimeExec pTimeExec) + { + _timerCallback = new TimerCallback(CheckTime); + _timer = new Timer(_timerCallback, null, 0, _Interval); + + _TimeExec = pTimeExec; + if(DateTime.Now.Hour <= pTimeExec.Hour) + { + if(DateTime.Now.Minute < pTimeExec.Minute) + { + //Todo-OK устанавливаем время запуска сегодня + _DateTimeExec = new DateTime(DateTime.Now.Year, + DateTime.Now.Month, + DateTime.Now.Day, + pTimeExec.Hour, + pTimeExec.Minute, + pTimeExec.Second); + } + else + { + //Todo-OK устанавливаем время запуска завтра + _DateTimeExec = new DateTime(DateTime.Now.Year, + DateTime.Now.Month, + DateTime.Now.Day, + pTimeExec.Hour, + pTimeExec.Minute, + pTimeExec.Second); + _DateTimeExec = _DateTimeExec.AddDays(1); + } + } + else + { + //Todo-OK устанавливаем время запуска завтра + _DateTimeExec = new DateTime(DateTime.Now.Year, + DateTime.Now.Month, + DateTime.Now.Day, + pTimeExec.Hour, + pTimeExec.Minute, + pTimeExec.Second); + _DateTimeExec = _DateTimeExec.AddDays(1); + } + } + + public delegate void CheckTimeHandler(DateTime pDateTimeExec); + //public delegate void CheckTimeHandler(); + + public event CheckTimeHandler? OnExecute; + private void CheckTime(object obj) + { + if (Run()) + { + OnExecute?.Invoke(_DateTimeExec); + _DateTimeExec = _DateTimeExec.AddHours(24); + } + } + + private bool Run() + { + bool _Exec = false; + DateTime _curDateTime = DateTime.Now; + _Exec = false; + if ((_curDateTime.Day == _DateTimeExec.Day) + &&(_curDateTime.Hour == _DateTimeExec.Hour) + && (_curDateTime.Minute == _DateTimeExec.Minute)) + { + _Exec = true; + } + return _Exec; + } + + } +} \ No newline at end of file diff --git a/Pfr.Services.Scheduler/TimeExec.cs b/Pfr.Services.Scheduler/TimeExec.cs new file mode 100644 index 0000000..fa86d2b --- /dev/null +++ b/Pfr.Services.Scheduler/TimeExec.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Pfr.Services.Scheduler +{ + public class TimeExec + { + private readonly int DefaultHour = 0; + private readonly int DefaultMinute = 0; + private readonly int DefaultSecond = 0; + + + private int _Hour; + private int _Minute; + private int _Second; + public TimeExec() + { + _Hour = DefaultHour; + _Minute = DefaultMinute; + _Second = DefaultSecond; + } + + + /// + /// Конструктор время выполнения + /// + /// час от 0 до 23 + /// мин от 0 до 59 + /// + public TimeExec(int hour, int minute) + { + InitProp(hour, minute); + Second = DefaultSecond; + } + + public TimeExec(int hour, int minute, int second) + { + InitProp(hour, minute); + if ((second > 59) || (second < 0)) + { + throw new ArgumentException(string.Format("second value from 0 to 59 this value {0}", second)); + } + Second = second; + } + private void InitProp(int hour, int minute) + { + if ((hour > 23) || (hour < 0)) + { + throw new ArgumentException(string.Format("hour value from 0 to 23 this value {0}", hour)); + } + if ((minute > 59) || (minute < 0)) + { + throw new ArgumentException(string.Format("minute value from 0 to 59 this value {0}", minute)); + } + Hour = hour; + Minute = minute; + } + + /// + /// мин от 0 до 59 + /// + public int Minute { get => _Minute; set => _Minute = value; } + + /// + /// час от 0 до 23 + /// + public int Hour { get => _Hour; set => _Hour = value; } + public int Second { get => _Second; set => _Second = value; } + } +} diff --git a/Pfr.Services.SchedulerTests/Pfr.Services.SchedulerTests.csproj b/Pfr.Services.SchedulerTests/Pfr.Services.SchedulerTests.csproj new file mode 100644 index 0000000..f4609a7 --- /dev/null +++ b/Pfr.Services.SchedulerTests/Pfr.Services.SchedulerTests.csproj @@ -0,0 +1,23 @@ + + + + net6.0 + enable + + false + + + + + + + + + + + + + + + + diff --git a/Pfr.Services.SchedulerTests/SchedulerTests.cs b/Pfr.Services.SchedulerTests/SchedulerTests.cs new file mode 100644 index 0000000..219c2c0 --- /dev/null +++ b/Pfr.Services.SchedulerTests/SchedulerTests.cs @@ -0,0 +1,64 @@ +using Xunit; +using Pfr.Services.Scheduler; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Threading; + +namespace Pfr.Services.Scheduler.Tests +{ + public class SchedulerTests + { + private TimeExec _te; + private int _CntExec = 0; + + public TimeExec GetTimeExec(int pSec) + { + TimeExec _TimeExec = new TimeExec(); + DateTime _dateTime = DateTime.Now.AddSeconds(pSec); + _TimeExec.Hour = _dateTime.Hour; + _TimeExec.Minute = _dateTime.Minute; + return _TimeExec; + } + + [Fact()] + public void SchedulerTest() + { + _te = GetTimeExec(2); + Scheduler _Scheduler = new Scheduler(_te); + _Scheduler.OnExecute += OnExecMetod; + Thread.Sleep(4000); + } + + private void OnExecMetod(DateTime pDateTimeExec) + { + Assert.Equal(pDateTimeExec.Hour, DateTime.Now.Hour); + Assert.Equal(pDateTimeExec.Minute, DateTime.Now.Minute); + } + + [Fact()] + public void Scheduler_Empty_OnExecute_Test() + { + _te = GetTimeExec(2); + Scheduler _Scheduler = new Scheduler(_te); + Thread.Sleep(4000); + } + + [Fact()] + public void Scheduler_One_Exec_Test() + { + _te = GetTimeExec(60); + Scheduler _Scheduler = new Scheduler(_te); + _Scheduler.OnExecute += OnExec; + Thread.Sleep(120000); + Assert.Equal(_CntExec, 1); + } + + private void OnExec(DateTime pDateTimeExec) + { + _CntExec += 1; + } + } +} \ No newline at end of file