"Мистическое" повторное срабатывание метода - C#
Формулировка задачи:
Здравствуйте! Есть таймер переодически запускающий метод OnTimedEvent:
Описываю работу этого метода. Получаем текущее время, сравниваем его с dtNext (время следующего запуска MyMethods()), если текущее время больше, то запускаем MyMethods(), а затем вычисляем время следующего запуска dtNext. По итогу MyMethods() должны запускаться примерно каждые полминуты получая на входе в качестве параметра dtNext - строгие тридцатисекундные отсечки времени, то есть не важно запустится MyMethods() в 12:25:33 или в 12:25:48, важно только то, что в качестве параметра он должен получить 12:25:30, что я и реализовал. Вроде все работало как надо, но в некоторые дни, я получал результат, что MyMethods() срабатывал два раза с одной и той же dtNext. Причем, самое интересное, это всегда было в 00:00:00, пару суток все работает как нужно и вдруг ровно в полночь MyMethods() срабатывает два раза с одним и тем же dtNext, прямо мистика Я предположил, что это происходит из-за того, что MyMethods() просто не успевает отработать до конца (чего то где то подвисает), а уже наступает следующий тик таймера поэтому он запускается снова с тем же dtNext и по итогу два метода параллельно отрабатывают в с одним и тем же параметром. Сделал защиту от этого, ввел флаг wasThereTheTick, как только происходит тик таймера он взводится в 1 и препятствует повторному запуску MyMethods() пока он не отработает до конца, не пересчитает dtNext, только тогда флаг сбросится.
Но и это не помогло, по прежнему иногда, ровно в полночь MyMethods() срабатывает два раза с одним и тем же dtNext. Посоветуйте, что еще можно сделать в таком случае и почему флаг не решил эту проблему?
private void WorkingTimer()
{
tm = new TimerCallback(OnTimedEvent);
timer = new System.Threading.Timer(tm, null, 0, 10000);
}private void OnTimedEvent(object source)
{
DateTime dtn = DateTime.Now;
try
{
if (wasThereTheTick == false)
{
wasThereTheTick = true;
if (dtn > dtNext)
{
MyMethods(dtNext);
if (dtn.Second < 30)
{
DateTime dtTemp = dtn.AddSeconds(30 - dtn.Second);
dtNext = new DateTime(dtTemp.Year, dtTemp.Month, dtTemp.Day, dtTemp.Hour, dtTemp.Minute, dtTemp.Second, 0);
}
else
{
DateTime dtTemp = dtn.AddSeconds(60 - dtn.Second);
dtNext = new DateTime(dtTemp.Year, dtTemp.Month, dtTemp.Day, dtTemp.Hour, dtTemp.Minute, dtTemp.Second, 0);
}
}
}
}
catch (Exception ex)
{
Logs errors = new Logs(dtn);
errors.WriteExceptionInFile(ex.ToString());
}
finally
{
wasThereTheTick = false;
}
}Решение задачи: «"Мистическое" повторное срабатывание метода»
textual
Листинг программы
MyMethods(dtNext.AddSeconds(-30))