Timer: остановить, дождаться завершения... Покритикуйте.
От: AK107  
Дата: 18.09.10 11:59
Оценка:
Реализую периодическое выполнение некоторых операций в фоне.
Задача: последовательное выполнение периодических задач, иметь возможность остановить выполнение, дождаться окончания выполнения фоновых операций.

Грубо: набор функций Start, Stop, Wait.

Я реализовал следующим образом (см код ниже). Покритикуйте пожалуйста (смущает черезчур сложный код с одновременным использованием как блокировки, флага, так и события. Можно ли упростить его?
using System.Threading;
using Timer = System.Timers.Timer;

public class Program
{
    private readonly object locker = new object();
    // признак простаивания
    private readonly ManualResetEvent evIdle = new ManualResetEvent(true);
    // не используем AutoReset, чтобы избежать араллельных вызовов в случае если длительность Work > Interval
    private readonly Timer timer = new Timer { Interval = 1, AutoReset = false };
    // флаг остановки
    private bool stop;

    public Program()
    {
        timer.Elapsed += Work;
    }

    void Work(object sender, System.Timers.ElapsedEventArgs e)
    {
        lock (locker)
        {
            // проверка если вызов был уже произведен ("запланирован") когда устанавливали флаг/останавливали таймер
            if (stop)
                return;
            evIdle.Reset();
        }
        // имитация длительной операции
        Thread.Sleep(3000);
        lock (locker)
        {
            if (!stop)
                timer.Start();
            evIdle.Set();
        }
    }

    public void Start()
    {
        Stop();
        Wait();
        stop = false;
        timer.Start();
    }

    public void Stop()
    {
        lock (locker)
        {
            stop = true;
            timer.Stop();
        }
    }

    public void Wait()
    {
        evIdle.WaitOne();
    }

    static void Main()
    {
        var program = new Program();
        program.Start();
        // пауза - дадим таймеру сработать
        Thread.Sleep(10);
        program.Stop();
        program.Wait();
    }
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.