Справочная информация:
- Запуск Windows Server 2008 R2.
- Серверы были исправлены всеми последними обновлениями.
- На сервере запущено 5 служб, встроенных в .NET 3.5, и все эти службы используют таймеры для повторной проверки базы данных (в основном каждые 10 секунд).
- Эти службы не интенсивно используют ЦП и ОЗУ.
- Сервер не имеет проблем с производительностью, ресурсами или узкими местами.
В большинстве случаев все работает как положено, но время от времени некоторые (или все) службы просто перестают работать. Я записываю все исключения приложения в файл, но в случае сбоя их нет. Также нет ошибок в регистраторе событий, и диспетчер служб рассматривает службы как работающие. Я должен остановить службы и запустить их еще раз, чтобы восстановить функциональность.
Это поведение непредсказуемо, иногда требуется неделя или месяц, прежде чем оно перестает работать. Кроме того, иногда службы «умирают» все вместе или только некоторые из них одновременно.
Единственное, что приходило мне в голову, это объект Таймера. Я использовал System.Timers.Timer и обнаружил несколько веток форума, заявляющих, что это ненадежно, поскольку сборщик мусора может освободить экземпляр. Я пытался сохранить его с помощью GC.KeepAlive () безрезультатно. Я следовал нескольким советам по перемещению System.Timers.Timer в System.Threading.Timer, но это тоже не имело никакого значения.
Прямо сейчас, я отчаянно пытаюсь выяснить источник этого поведения. Есть ли известная похожая проблема? Как я могу его отладить, если не возникло исключение и журнал событий тоже молчит?
Спасибо за любой совет, который может привести к любому решению.
ОБНОВЛЕНИЕ: включая код текущего состояния:
private System.Threading.Timer timerPublish = null;
private bool timerDelegateMethodRunning = false;
protected override void OnStart(string[] args)
{
SetupTimer();
}
protected override void OnStop()
{
if (timerPublish != null)
{
timerPublish.Dispose();
}
}
public void SetupTimer()
{
if (timerPublish != null)
{
timerPublish.Dispose();
}
TimerCallback callbackMethod = new TimerCallback(this.timerPublish_Elapsed);
timerPublish = new System.Threading.Timer(callbackMethod, null, 5000, 5000);
}
void timerPublish_Elapsed(Object stateInfo)
{
if (timerDelegateMethodRunning)
{
return;
}
timerDelegateMethodRunning = true;
try
{
// Processing code here
}
finally
{
timerDelegateMethodRunning = false;
}
}
ОБНОВЛЕНИЕ2: Спасибо вам, ребята, за ваши идеи и советы. Я попытаюсь отладить службы на производственном сервере, как только проблема повторится. Я сообщу, как только у меня будет что-нибудь новое (вероятно, через несколько недель).