2013-09-13 3 views
1

Ниже представлен класс из. Net службы Windows. Метод DoSomeDatabaseStuff занимает 10 минут, когда он запускается в первый раз, но по истечении этого времени этот метод больше не вызывается.C# Таймер с истекшим временем не вызывает метод

public class Test 
{ 
     public void Start() 
     { 
      DoSomeDatabaseStuff(); 

      _oTimer = new Timer(60000); 
      _oTimer.Elapsed += OnTimeout; 
      _oTimer.AutoReset = true; 
      _oTimer.Start(); 
     } 

     private void OnTimeout(object source, ElapsedEventArgs e) 
     { 
      DoSomeDatabaseStuff(); 

      _oTimer = new Timer(60000); 
      _oTimer.Elapsed += OnTimeout; 
      _oTimer.AutoReset = true; 
      _oTimer.Start(); 
     } 
} 
+0

Вы пытались поставить точку останова в своем методе 'OnTimeout'? –

+0

Нет необходимости в повторной инициализации '_oTimer' внутри' OnTimeout', так как у вас 'AutoReset' установлено значение' true'. –

+1

60000 мс - одна минута, а не 10;) –

ответ

1

Вместо того чтобы создавать новый таймер каждый раз, попытайтесь установить обработчик OnTimeout к:

_oTimer.Stop(); 
DoSomeDatabaseStuff(); 
_oTimer.Start(); 

аналогично методу Start().

+2

На самом деле это не проблема для проблемы повторного входа. Нет никакой гарантии, что обработчик события Elapsed будет запускаться, когда отметки таймера будут зависеть от диспетчеризации диспетчера потоков. Если задержка достаточно длинная, то второй вызов мог быть запланирован, но еще не выполнен. Все еще вызывает повторное включение. Установка свойства AutoReset таймера на false - это простой и правильный способ. –

3

Я использую System.Threading.Timer в окнах-услуг.

Может быть, это решает также проблему, так как другие имеют также проблемы с System.Timers.Timer в окнах-услуг:. «То, что я обнаружил, что System.Timers.Timer просто не работает в моем приложении службы Windows, поэтому я переключился в System.Threading.Timer "

См: Windows Service System.Timers.Timer not firing

private void InitService() 
{ 
    //starts immediately, interval is in TimeSpan 
    this._oTimer = new System.Threading.Timer(
     OnTimeout, 
     null, 
     TimeSpan.Zero, 
     TimeSpan.FromMinutes(10) 
    ); 
} 

protected override void OnStart(string[] args) 
{ 
    InitService(); 
} 

protected override void OnStop() 
{ 
    this._oTimer.Change(System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite); 
} 

private void ImportTimer_Elapsed(Object state) 
{ 
    DoSomeDatabaseStuff(); 
} 
2

Ваша программа заканчивается до запуска таймера. Timer работает в background thread Ведьма заканчивается, когда основная нить останавливается.

попробовать

static void Main(string[] args) 
{ 
    Test t = new Test(); 
    t.Start(); 
    Console.ReadLine(); 
} 
5

Есть много серьезных проблем в этом коде:

  • Если метод Start предназначается, чтобы быть метод OnStart() службы, то вы никогда не можете получить началось обслуживание. OnStart() должен завершиться менее чем за 30 секунд. Просто инициализируйте таймер и ничего не делайте.
  • Создание еще одного таймера в обработчике прошедшего события является серьезной ошибкой. Обработчик событий будет работать дважды. После второго раза его называют «трижды». Etcetera.
  • Ваша тестовая программа не проверяет, как код будет работать в службе. Обработчик события Elapsed никогда не будет запущен, так как тест будет выполнен до запуска обработчика событий. Который объясняет ваше наблюдение
  • Вы должны использовать try/catch в обработчике событий Elapsed. Если вы этого не сделаете, любое исключение будет проглочено без диагностики. Класс System.Timers.Timer такой противный, предпочитает System.Threading.Timer вместо этого Также объясняет ваше наблюдение
  • Вы должны должны убедиться, что ваш обработчик событий является повторным. Он может работать снова, когда предыдущий вызов обработчика событий все еще занят, это произойдет, когда задача занимает больше минуты. Это очень редко заканчивается. Установка AutoReset = false - это простой способ избежать этого повторного входа, запустите таймер в конце обработчика событий, чтобы его повторить.
Смежные вопросы