Система.Многопоточность.Таймер не тикает на Windows Server 2003

#c# #.net #timer

#c# #.net #таймер

Вопрос:

В настоящее время у меня возникли проблемы с системой.Многопоточность.Таймер при развертывании моей службы Windows на сервере Win2k3. Он отлично работает, отсчитывая каждую секунду (перебор для целей отладки) на моем локальном компьютере, когда я его устанавливаю, но после того, как я установлю его на сервер, служба запускается успешно, а затем никогда не запускает событие таймера один раз. Кто-нибудь сталкивался с ситуацией, подобной этой, раньше? Большинство моих исследований выявили проблемы, которые, по-видимому, были распространены в .NET 1.1 целую вечность назад. Спасибо за ваше время и помощь.

    protected override void OnStart(string[] args)
   {
        int interval = Int32.Parse(ConfigurationManager.AppSettings["SleepTime"]) * 1000;
        TimerCallback cb = new TimerCallback(ProcessTimerEvent);
        QueueWorker worker = new QueueWorker();
        workTimer = new Timer(cb, worker, interval, 1000);

    }
    private static void ProcessTimerEvent(object obj)
    {
        if (obj is QueueWorker)
        {
            QueueWorker qw = (QueueWorker)obj;
            qw.doWork();
        }
    }
    class QueueWorker
    {
        public void doWork()
        {
           // work happening here
        }
    }
  

Обновить:

Я обнаружил, что это как-то связано с пользователем, от имени которого должна запускаться служба. Когда служба запускается как система, потоки работают отлично. Кто-нибудь знает, какие разрешения необходимы пользователю для запуска потоков? Я попытался использовать «Действовать как часть операционной системы» в локальных настройках безопасности, но это просто приводит к запуску службы, а затем к немедленному сбою при входе в систему как добавленный мной пользователь.

Комментарии:

1. Действительно очевидный вопрос: какое значение app.Config для SleepTime на сервере? Другой вариант: использовать System.Timers.Timer вместо этого.

2. У меня была система. Таймеры. Таймер, прежде чем я реализовал его таким образом. Я получил такое же поведение на своем сервере, служба запустится, тогда событие таймера никогда не сработает. Затем я прочитал, что сервер Win 2k3 выполняет некоторые забавные операции с потоками, и этот таймер может работать не так, как я ожидал. Значение времени ожидания прямо сейчас составляет 1 секунду для моих целей тестирования. Позже это будет то, что мне нужно, когда я не тестирую.

3. Можете ли вы опубликовать ссылки, касающиеся поведения w2k3? Можете ли вы создать консольное тестовое приложение, чтобы исключить работу службы win? Это также было бы намного проще протестировать Console.WriteLine . И, извините, что задаю глупые вопросы, SleepTime 1000 миллисекунд = 1 секунде, верно?

4. Вероятно, я мог бы создать консольное тестовое приложение, но я считаю, что проблема с сервером Win2k3 заключалась в том, что с самого начала проблема заключалась в потоковой передаче в службах. И да, 1000 мс = 1 сек.

Ответ №1:

Возможно, таймер срабатывает. Вы можете запустить DebugView на целевой машине:

http://technet.microsoft.com/en-us/sysinternals/bb896647.aspx

Затем вы можете поместить вызовы в свой код, чтобы увидеть, что выполняется следующим образом:

 System.Diagnostics.Debug.WriteLine("Beginning of Timer event...");

System.Diagnostics.Debug.WriteLine("End of Timer event");
  

Комментарии:

1. У меня есть сообщение о событии, которое нужно запустить, когда это произойдет, но я ничего не получаю. Также работа внутри таймера не завершается. Я установил его без таймера, просто запустив часть DoWork (), и он ведет себя так, как я и ожидал, даже записывает в журнал событий, где и должен. Таким образом, это полностью связано с таймерами и потоковой обработкой.

2. Интересно, не имеет ли пользователь, под которым запущена служба, доступа к: ConfigurationManager. Настройки приложений [«Время сна»]? Это не имеет смысла, но вы могли бы жестко закодировать значение вместо его чтения и посмотреть, поможет ли это.

3. @mtgibbs21: я бы также посоветовал убедиться, что OnStart метод действительно запускает таймер, как вы ожидаете. Вы должны ввести некоторый код, который выводит сообщение при OnStart вызове, значение interval , а также при OnStart завершении. Мне кажется, что таймер не создается.

4. interval Значение заполняется правильно, и создается экземпляр таймера при запуске от имени моего пользователя. Просто по какой-то причине OnStart метод просто завершает весь путь до конца, и поток никогда не запускается по таймеру. Опять же, запуск службы как Local System устраняет проблему с тем, что таймер не запускается, но он больше не запускается как требуемый пользователь для выполнения своей работы.

5. Я также добавил этого пользователя к локальным администраторам на компьютере, но, похоже, это не помогает.

Ответ №2:

Я могу предложить пару решений:

  1. Используйте консольное приложение, а не службу Windows. Запустите консольное приложение из планировщика задач.
  2. Создайте свой собственный класс timer. Используйте свои собственные потоки и переходите в режим ожидания для интервала опроса. После пробуждения выполняйте свою работу. Затем снова переходите в спящий режим.

И для полноты картины, вот некоторые из статей, в которых подробно описывается фактическая ошибка:

Комментарии:

1. Это хорошая подборка информации. Я собираюсь пометить это как решение, чтобы люди знали, что их нужно прочитать.

Ответ №3:

Хорошо. Спасибо за все ваши предложения по этому поводу. Я создал очень агрессивную схему ведения журнала, и я считаю, что сервер по какой-то причине отключал мои потоки. Я добавил GC.KeepAlive(workTimer) и, похоже, решил проблему с тем, что таймер не тикает.

На всякий случай, если кто-то еще столкнется с этой проблемой, мне кажется, что локальная система получает приоритет потока, но другие пользователи потенциально могут уничтожить свои потоки по той или иной причине. Поскольку у меня нет полного доступа к серверу, на котором я это развертываю, я запишу исправление в KeepAlive или команда сервера исправила что-то за моей спиной.

Комментарии:

1. Рад, что вы нашли какой-то способ заставить это работать. Я опубликовал некоторые другие возможные решения, которые могут быть полезны вам (но, возможно, и другим), а могут и не быть полезными. И некоторые статьи, в которых подробно описывается ошибка.