2010-09-03 4 views
17

У меня есть приложение для работы с окнами. И отлаживаем его, работая в консольном режиме.System.Threading.Timer не срабатывает через некоторое время

Здесь http://support.microsoft.com/kb/842793 написано, что Timers.Timer имеет ошибку и не стреляет в сервисы windows. И обходным путем является использование Threading.Timer И эта статья предназначена для .NET 1.0 и 1.1

Я использую .NET 4, но через некоторое время Threading.Timer также не запускается. Так что же может быть причиной этого? И что вы можете предложить в качестве обходного пути?

Спасибо,

С наилучшими пожеланиями

EDIT: Я изменил таймер от Threading.Timer до Timers.Timer и работает без каких-либо проблем.

+1

Я думаю, что хорошим способом ускорить решение этой проблемы является публикация и запуск начального кода таймера. – Vokinneberg

+0

Использование любого неуправляемого кода? –

+0

Я вызываю функцию из родной win32 dll, но она находится на другом потоке – AFgone

ответ

47

Вы держите ссылку на свой таймер где-нибудь, чтобы предотвратить сбор мусора?

От the docs:

Пока вы используете таймер, вы должны сохранить ссылку на него. Как и в случае с , любой управляемый объект, Таймер является предметом для сбора мусора, когда есть Нет ссылок на него. Тот факт, что таймер по-прежнему активен, не предотвращает его сбор .

+0

да есть ссылка на таймер – AFgone

+2

@AFgone: Где же? Как ты уверен, что это не сбор мусора? –

+2

+1 - Я люблю тебя, Джон Скит, это сводило меня с ума :) – Tr1stan

4

Работать вокруг?

Лично я предлагаю использовать функцию RegisterWaitForSingleObject в отличие от таймеров для точной причины, по которой вы работаете. RegisterWaitForSingleObject регистрирует делегат, который будет вызываться на интервале, который вы устанавливаете аналогичным для таймера, и супер легко реализуется. В течение нескольких часов вы можете иметь тестовую проводку. Я использую этот метод интервальной стрельбы в своих службах Windows, и это надежное и надежное решение, которое работает для меня.

Прочтите приведенную ниже ссылку и перейдите по ссылкам в статье для образцов кода и прохождений.

Запуск периодического процесса в .NET с помощью службы Windows:
http://allen-conway-dotnet.blogspot.com/2009/12/running-periodic-process-in-net-using.html

4

Вашего объект таймер выходит из области видимости и стирается сборщик мусора через некоторое время, которое останавливает обратные вызовы от стрельбы.

Сохраните ссылку на него в члене класса.

0

Полный пример службы Windows с использованием корпоративной библиотеки для ведения журнала и повторяющихся потоков. Удалите строки logger.write, если не используете библиотеку entreprise.

namespace Example.Name.Space 
{ 
public partial class SmsServices : ServiceBase 
{ 
    private static String _state = "";   
    private ManualResetEvent _stop = new ManualResetEvent(false); 
    private static RegisteredWaitHandle _registeredWait; 
    public WindowsServices() 
    { 
     InitializeComponent(); 
    } 

    protected override void OnStart(string[] args) 
    {       
     Logger.Write("Starting service", LoggerCategory.Information);    
     _stop.Reset(); 
     _registeredWait = ThreadPool.RegisterWaitForSingleObject(_stop, 
      PeriodicProcess, null, 5000, false); 

    } 

    protected override void OnStop() 
    {    
     // UpdateTimer.Stop(); 
     _stop.Set(); 
     Logger.Write("Stopping service", LoggerCategory.Information); 
    }   
    private static void PeriodicProcess(object state, bool timedOut) 
    { 

     if (timedOut) 
     { 
      // Periodic processing here 
      Logger.Write("Asserting thread state", LoggerCategory.Debug); 
      lock (_state) 
      { 
       if (_state.Equals("RUNNING")) 
       { 
        Logger.Write("Thread already running", LoggerCategory.Debug); 
        return; 
       } 
       Logger.Write("Starting thread", LoggerCategory.Debug); 
       _state = "RUNNING"; 
      } 
      Logger.Write("Processing all messages", LoggerCategory.Information); 
      //Do something 
      lock (_state) 
      { 
       Logger.Write("Stopping thread", LoggerCategory.Debug); 
       _state = "STOPPED"; 
      } 
     } 
     else 
      // Stop any more events coming along 
      _registeredWait.Unregister(null); 


    } 
    } 
} 
Смежные вопросы