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();
    }
}
Re: Timer: остановить, дождаться завершения... Покритикуйте.
От: AK107  
Дата: 20.09.10 03:53
Оценка:
Здравствуйте.

Все молчат, наверное код идеален...

Ну а если серьезно, то все еще жду конструктивных замечаний.
Re[2]: Timer: остановить, дождаться завершения... Покритикуй
От: achmed Удмуртия https://www.linkedin.com/in/nail-achmedzhanov-9907188/
Дата: 20.09.10 06:59
Оценка: 1 (1)
Здравствуйте, AK107, Вы писали:

AK>Здравствуйте.


AK>Все молчат, наверное код идеален...


AK>Ну а если серьезно, то все еще жду конструктивных замечаний.


Попробуй проверить c CHESS
Re[3]: Timer: остановить, дождаться завершения... Покритикуй
От: AK107  
Дата: 20.09.10 10:34
Оценка:
Здравствуйте, achmed, Вы писали:

A>Попробуй проверить c CHESS



потестил: вместо таймера стартовал поток из которого вызывался Work, из другого же поток звал stop и wait.
говорит все гуд.

подтвердил лишь для себя следующие моменты:

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


1* — evIdle.Reset нельзя выносить за lock, тк Stop и Wait могут быть вызваны между блоком lock и evIdle.Reset.
2* — evIdle.Set можно выносить за lock и ставить его как до так и после рестарта таймера, тк они не связаны в атомарную операцию.

з.ы. то, что работает без ошибок я в принципе знал (скромно так ), я больше хочу услышать критику и возможные шаги по упрощению кода.
Re[4]: Timer: остановить, дождаться завершения... Покритикуй
От: achmed Удмуртия https://www.linkedin.com/in/nail-achmedzhanov-9907188/
Дата: 20.09.10 10:40
Оценка:
Здравствуйте, AK107, Вы писали:

AK>з.ы. то, что работает без ошибок я в принципе знал (скромно так ), я больше хочу услышать критику и возможные шаги по упрощению кода.


А задача конечная есть или это просто придуманные условия?
Re[5]: Timer: остановить, дождаться завершения... Покритикуй
От: AK107  
Дата: 20.09.10 10:49
Оценка:
Здравствуйте, achmed, Вы писали:

A>А задача конечная есть или это просто придуманные условия?


конечно. все реально.

нужно с некоторой периодичностью выполнять некую операцию (выбрал таймер, отдельный поток не хочу). нужно уметь корректино остановить такую периодическую обработку, и, если нужно дождаться окончания обработки (если такова была уже запущена на момент остановки). методы остановки и ожидания иметь отдельно, тк есть другие фоновые потоки обработчики — хочу всем дать команду "остановится" и по очереди дождатья завершения.

з.ы. как по мне, так часто встречающаяся задача неужели никто не сталкивался? или никого не заботит как оно там корректно отработает?
Re[6]: Timer: остановить, дождаться завершения... Покритикуй
От: achmed Удмуртия https://www.linkedin.com/in/nail-achmedzhanov-9907188/
Дата: 20.09.10 11:40
Оценка: +1
Здравствуйте, AK107, Вы писали:

AK>конечно. все реально.


AK>нужно с некоторой периодичностью выполнять некую операцию (выбрал таймер, отдельный поток не хочу). нужно уметь корректино остановить такую периодическую обработку, и, если нужно дождаться окончания обработки (если такова была уже запущена на момент остановки). методы остановки и ожидания иметь отдельно, тк есть другие фоновые потоки обработчики — хочу всем дать команду "остановится" и по очереди дождатья завершения.


А что делают обработчики, кто или что ими управляет?

AK>з.ы. как по мне, так часто встречающаяся задача неужели никто не сталкивался? или никого не заботит как оно там корректно отработает?


Именно таких задач мне не встречалось .
А по коду — вроде нормально написан .
Re[7]: Timer: остановить, дождаться завершения... Покритикуй
От: AK107  
Дата: 20.09.10 12:19
Оценка:
Здравствуйте, achmed, Вы писали:

A>А что делают обработчики, кто или что ими управляет?

если я правильно понял вопрос, то обработка — это например вызов некоторых вебсервисов в фоне и сбор данных... управления как такого нет: при старте программы запускается таймер, при завршении хочу корректно останавливать периодическую обработку

A>Именно таких задач мне не встречалось .

ну а например, чекать почту раз в минуту, очередь задач (внешнюю, в БД например)?..

A>А по коду — вроде нормально написан .

пасип.

смущает, что как то там много всего одновременно используется для сигнализации
Re[7]: Timer: остановить, дождаться завершения... Покритикуй
От: AK107  
Дата: 20.09.10 12:21
Оценка:
Здравствуйте, achmed, Вы писали:

A>А что делают обработчики, кто или что ими управляет?


посмотрел на код и дошло в чем вопрос. нет, параллельных вызовов Start/Stop/Wait нет. строго последовательно. из одного потока.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.