Моя цель — написать фрагмент кода, который позволит мне иметь эксклюзивный доступ к объекту (например, txt-файлу) в параллельной среде. Имея это в виду, я тестировал простую программу, построенную на использовании двух таймеров System.Timers. Обработчики событий обоих таймеров совместно используют один и тот же объект блокировки (см. код ниже).
Таймеры запускаются одновременно с разным интервалом: 3 с для таймера 1 и 1 с для таймера 2. Timer1 должен работать только в течение одного цикла, в течение которого его обработчик событий будет спать в течение 10 секунд и, таким образом, сохранять блокировку.
Что меня удивило, так это то, что когда блокировка снимается, я не получаю все события timer2 в памяти (только прил. каждый второй из них). Я думал, пока обработчик событий timer1 имеет блокировку, события timer2 складываются в память. Но это, видимо, неправда. Почему некоторые события timer2 исчезают?
class Program
{
static int counter = 0;
static readonly object locker = new object();
System.Timers.Timer timer1;
System.Timers.Timer timer2;
static void Main(string[] args)
{
Program p = new Program();
p.timer1 = new System.Timers.Timer(3000);
p.timer1.Elapsed += new ElapsedEventHandler(p.Timer1EventHandler);
p.timer1.Start();
p.timer2 = new System.Timers.Timer(1000);
p.timer2.Elapsed += new ElapsedEventHandler(p.Timer2EventHandler);
p.timer2.Start();
ThreadPool.SetMaxThreads(50, 50);
Console.ReadLine();
}
void Timer1EventHandler(object sender, ElapsedEventArgs e)
{
timer1.Stop();
DoThingsForTimer1Event();
}
void DoThingsForTimer1Event()
{
lock (locker)
{
Console.WriteLine(DateTime.Now + " Timer1 event started." + " Current thread number " + Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(10000);
Console.WriteLine(DateTime.Now + " Timer1 event finished. Lock released.");
}
}
void Timer2EventHandler(object sender, ElapsedEventArgs e)
{
counter++;
lock (locker)
{
Console.WriteLine(DateTime.Now + " Timer2 event fired. Current thread number " + Thread.CurrentThread.ManagedThreadId +
" Counter=" + counter);
}
}
}