Что вам нужно, так это возможность отвечать на уведомления о двух разных событиях - (1) по истечении таймера и (2) при остановке службы. @ Anurag Ranhjan находится на правильном пути с WaitHandle
, но у вас есть два события, а не одно. Чтобы правильно справиться с этим, сделайте следующее.
Сначала определите два события, которые вас интересуют, используя ManualResetEvent
. Вы можете использовать AutoResetEvent
, если хотите; Я просто предпочитаю сброс событий вручную.
using System.Threading;
ManualResetEvent shutdownEvent = new ManualResetEvent();
ManualResetEvent elapsedEvent = new ManualResetEvent();
Вам нужно запускать эти события, когда они происходят. Для shutdownEvent
это легко. В обратном вызове OnStop
вашей службы Windows просто установите событие.
protected override void OnStop
{
shutdownEvent.Set();
}
Для elapsedEvent
вы можете сделать это несколькими разными способами. Вы можете создать фоновый поток, то есть ThreadPool
, который использует Thread.Sleep
. Когда поток проснется, установите elapsedEvent
и вернитесь в спящий режим. Так как это фоновый поток, он не повесит ваш сервис при завершении работы. Альтернативой, как вы уже предложили, является использование таймера. Вот как я это делаю.
using System.Timers;
Timer timer = new Timer();
timer.Interval = 5000; // in milliseconds
timer.Elapsed += delegate { elapsedEvent.Set(); };
timer.AutoReset = false; // again, I prefer manual control
timer.Start();
Теперь, когда вы правильно настроили события, поместите их в массив WaitHandle
.
WaitHandle[] handles = new WaitHandle[]
{
shutdownEvent,
elapsedEvent
};
Вместо метода WaitHandle.WaitOne
используйте метод WaitHandle.WaitAny
внутри цикла while, как этот.
while (!shutdownEvent.WaitOne())
{
switch (WaitHandle.WaitAny(handles))
{
case 0: // The shutdownEvent was triggered!
break;
case 1: // The elapsedEvent was triggered!
Process(); // do your processing here
elapsedEvent.Reset(); // reset the event manually
timer.Start(); // restart the timer manually
break;
default:
throw new Exception("unexpected switch case");
}
}
Я сжал этот пример из производственного кода в моем проекте. Я знаю, что этот механизм работает, но я мог что-то пропустить в рецензии. Дайте мне знать, если у вас есть какие-либо вопросы.