Резюме: В рамках службы Windows и консольного приложения я вызываю общую библиотеку, содержащую таймер, который периодически запускает действие, выполнение которого занимает около 30 секунд. Однако это работает нормально ...
Когда вызывается остановка службы или выход приложения, а таймер находится в ElapsedEventHandler, мне нужно, чтобы остановка службы / выход приложения подождали, пока не завершится обработчик событий.
Я реализовал эта функциональность достигается за счет наличия логического свойства InEvent, которое проверяется при вызове метода остановки таймера.
Хотя это и работает, возникает вопрос: это лучший способ сделать это? Есть ли альтернативный подход, который может лучше служить этой цели?
Другая проблема заключается в том, что мне нужно избегать сбоя запроса остановки службы с сообщением «Служба не ответила на запрос остановки»
Это моя реализация
public sealed class TimedProcess : IDisposable
{
static TimedProcess singletonInstance;
bool InEvent;
Timer processTimer;
private TimedProcess()
{
}
public static TimedProcess Instance
{
get
{
if (singletonInstance == null)
{
singletonInstance = new TimedProcess();
}
return singletonInstance;
}
}
public void Start(double interval)
{
this.processTimer = new Timer();
this.processTimer.AutoReset = false;
this.processTimer.Interval = interval;
this.processTimer.Elapsed += new ElapsedEventHandler(this.processTimer_Elapsed);
this.processTimer.Enabled = true;
}
public void Stop()
{
if (processTimer != null)
{
while (InEvent)
{
}
processTimer.Stop();
}
}
void processTimer_Elapsed(object sender, ElapsedEventArgs e)
{
try
{
InEvent = true;
// Do something here that takes ~30 seconds
}
catch
{
}
finally
{
InEvent = false;
processTimer.Enabled = true;
}
}
public void Dispose()
{
if (processTimer != null)
{
Stop();
processTimer.Dispose();
}
}
}
И вот как он вызывается в сервисе OnStart / console application main:
TimedProcess.Instance.Start(1000);
Вот как он вызывается в сервисе OnStop и главном приложении (ожидающее нажатие клавиши):
TimedProcess.Instance.Stop();