Ожидание завершения события истекшего таймера до закрытия / остановки приложения / службы

Резюме: В рамках службы 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();
11
задан MrEyes 12 August 2011 в 16:31
поделиться