Реализую периодическое выполнение некоторых операций в фоне.
Задача: последовательное выполнение периодических задач, иметь возможность остановить выполнение, дождаться окончания выполнения фоновых операций.
Грубо: набор функций 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();
}
}