Подтвердить что ты не робот

System.Threading.Timer не срабатывает через некоторое время

У меня есть приложение для Windows. И отлаживая его, запустив консольный режим.

Здесь 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 и работает без проблем.

4b9b3361

Ответ 1

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

От документы:

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

Ответ 2

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

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

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

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

Ответ 3

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

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

Ответ 4

Полный пример службы 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);


    }
    }
}