Пример #1
0
        private void _Timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            bool continueNext = true;
            try
            {
                var now = e.SignalTime;
                _Timer.Stop();
                var doAlarm = false;
                long seconds;
                DateTime start, alarmDate;
                var changeZone = _Schedule.TimeZone != TimeZoneInfo.Local;

                switch (_Schedule.Type)
                {
                    case ScheduleType.Once:
                        alarmDate = changeZone
                            ? TimeZoneInfo.ConvertTime(_Schedule.AlarmDate, TimeZoneInfo.Local, _Schedule.TimeZone)
                            : _Schedule.AlarmDate;
                        if (alarmDate.IsDateEqual(now))
                        {
                            doAlarm = true;
                            continueNext = false;
                        }
                        break;
                    case ScheduleType.After:
                        start = _Schedule.StartFrom == ScheduleStart.ExactTime
                            ? (changeZone
                                ? TimeZoneInfo.ConvertTime(_Schedule.StartDate, TimeZoneInfo.Local, _Schedule.TimeZone)
                                : _Schedule.StartDate)
                            : PNStatic.StartTime;
                        PNStatic.NormalizeStartDate(ref start);
                        seconds = (now - start).Ticks / TimeSpan.TicksPerSecond;
                        if (seconds == _Schedule.AlarmAfter.TotalSeconds)
                        {
                            doAlarm = true;
                            continueNext = false;
                        }
                        break;
                    case ScheduleType.RepeatEvery:
                        if (_Schedule.LastRun == DateTime.MinValue)
                        {
                            start = _Schedule.StartFrom == ScheduleStart.ExactTime
                                ? (changeZone
                                    ? TimeZoneInfo.ConvertTime(_Schedule.StartDate, TimeZoneInfo.Local,
                                        _Schedule.TimeZone)
                                    : _Schedule.StartDate)
                                : PNStatic.StartTime;
                        }
                        else
                        {
                            start = _Schedule.LastRun;
                        }
                        PNStatic.NormalizeStartDate(ref start);

                        seconds = (now - start).Ticks / TimeSpan.TicksPerSecond;

                        if (seconds == _Schedule.AlarmAfter.TotalSeconds || (seconds > 0 && seconds % _Schedule.AlarmAfter.TotalSeconds == 0))
                        {
                            doAlarm = true;
                        }
                        break;
                    case ScheduleType.EveryDay:
                        alarmDate = changeZone
                            ? TimeZoneInfo.ConvertTime(_Schedule.AlarmDate, TimeZoneInfo.Local, _Schedule.TimeZone)
                            : _Schedule.AlarmDate;
                        if (alarmDate.IsTimeEqual(now)
                            && (_Schedule.LastRun == DateTime.MinValue || _Schedule.LastRun <= now.AddDays(-1)))
                        {
                            doAlarm = true;
                        }
                        break;
                    case ScheduleType.Weekly:
                        alarmDate = changeZone
                            ? TimeZoneInfo.ConvertTime(_Schedule.AlarmDate, TimeZoneInfo.Local, _Schedule.TimeZone)
                            : _Schedule.AlarmDate;
                        if (alarmDate.IsTimeEqual(now))
                        {
                            if (_Schedule.Weekdays.Contains(now.DayOfWeek)
                                && (_Schedule.LastRun == DateTime.MinValue || _Schedule.LastRun <= now.AddDays(-1)))
                            {
                                doAlarm = true;
                            }
                        }
                        break;
                    case ScheduleType.MonthlyExact:
                        alarmDate = changeZone
                            ? TimeZoneInfo.ConvertTime(_Schedule.AlarmDate, TimeZoneInfo.Local, _Schedule.TimeZone)
                            : _Schedule.AlarmDate;
                        if (alarmDate.Day == now.Day)
                        {
                            if (alarmDate.IsTimeEqual(now))
                            {
                                if (_Schedule.LastRun == DateTime.MinValue
                                    || _Schedule.LastRun.Month < now.Month
                                    || _Schedule.LastRun.Year < now.Year)
                                {
                                    doAlarm = true;
                                }
                            }
                        }
                        break;
                    case ScheduleType.MonthlyDayOfWeek:
                        if (now.DayOfWeek == _Schedule.MonthDay.WeekDay)
                        {
                            alarmDate = changeZone
                                ? TimeZoneInfo.ConvertTime(_Schedule.AlarmDate, TimeZoneInfo.Local, _Schedule.TimeZone)
                                : _Schedule.AlarmDate;
                            if (alarmDate.IsTimeEqual(now))
                            {
                                bool isLast = false;
                                int ordinal = PNStatic.WeekdayOrdinal(now, _Schedule.MonthDay.WeekDay, ref isLast);
                                if (_Schedule.MonthDay.OrdinalNumber == DayOrdinal.Last)
                                {
                                    if (isLast)
                                    {
                                        if (_Schedule.LastRun == DateTime.MinValue
                                            || _Schedule.LastRun.Month < now.Month
                                            || _Schedule.LastRun.Year < now.Year)
                                        {
                                            doAlarm = true;
                                        }
                                    }
                                }
                                else
                                {
                                    if ((int)_Schedule.MonthDay.OrdinalNumber == ordinal)
                                    {
                                        if (_Schedule.LastRun == DateTime.MinValue
                                            || _Schedule.LastRun.Month < now.Month
                                            || _Schedule.LastRun.Year < now.Year)
                                        {
                                            doAlarm = true;
                                        }
                                    }
                                }
                            }
                        }
                        break;
                    case ScheduleType.MultipleAlerts:
                        foreach (var ma in _Schedule.MultiAlerts.Where(a => !a.Raised))
                        {
                            alarmDate = changeZone
                                ? TimeZoneInfo.ConvertTime(ma.Date, TimeZoneInfo.Local, _Schedule.TimeZone)
                                : ma.Date;
                            if (!alarmDate.IsDateEqual(now)) continue;
                            ma.Checked = true;
                            doAlarm = true;
                            break;
                        }
                        break;
                }
                if (doAlarm)
                {
                    if (!PNStatic.FormMain.Dispatcher.CheckAccess())
                    {
                        _ElapsedDelegate d = _Timer_Elapsed;
                        PNStatic.FormMain.Dispatcher.Invoke(d, sender, e);
                    }
                    else
                    {
                        bool save = false;
                        switch (_Schedule.Type)
                        {
                            case ScheduleType.EveryDay:
                            case ScheduleType.RepeatEvery:
                            case ScheduleType.Weekly:
                            case ScheduleType.MonthlyExact:
                            case ScheduleType.MonthlyDayOfWeek:
                                _Schedule.LastRun = now;
                                save = true;
                                break;
                            case ScheduleType.MultipleAlerts:
                                var ma = _Schedule.MultiAlerts.FirstOrDefault(a => a.Checked);
                                if (ma != null)
                                {
                                    ma.Checked = false;
                                    ma.Raised = true;
                                }
                                save = true;
                                break;
                        }
                        PNStatic.FormMain.ApplyDoAlarm(this);
                        if (save)
                        {
                            PNNotesOperations.SaveNoteSchedule(this);
                        }
                        if (!continueNext)
                        {
                            PNNotesOperations.DeleteNoteSchedule(this);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                PNStatic.LogException(ex);
            }
            finally
            {
                if (continueNext)
                {
                    _Timer.Start();
                }
            }
        }