System.Timers.Timer и Lock - C#
Формулировка задачи:
Добрый день.
Почитал немного про Thread Safety, про ThreadPool, про синхронизацию потоков.
Но всё равно что-то не сходится, потому прошу пояснить, если возможно.
Вопрос:
Как именно работает System.Timers.Timer в плане создания потоков?
Сделал простой код. Нажимаю кнопку, запускаю таймер с интервалом 1 мс. Внутри выполняется функция ScreenCapture, которая (по результатам теста) выполняется где-то 15 мс. Как я думал, потоки будут перекрывать друг друга и нужна будет блокировка или какая-то другая синхронизация. Использовал lock, использовал Monitor.TryEnter (с разными значениями), использовал AutoReset = false. Удивительно, что в любом варианте вывод на экран был одинаковый с небольшими колебаниями ("15600 / 1000"). Получается, что следующий поток таймера всё-таки ждёт окончания предыдущего и никакие локи не нужны? На форумах нашёл очень много про блокировки в таймерах, везде советуют их использовать. Почему так получается?
Листинг программы
- private void button1_Click(object sender, EventArgs e)
- {
- test = 0;
- System.Timers.Timer test_timer = new System.Timers.Timer();
- test_timer.Interval = 1;
- test_timer.Elapsed += test_timer_Tick;
- //test_timer.AutoReset = false;
- sw = new Stopwatch();
- sw.Start();
- test_timer.Start();
- }
- public void test_timer_Tick(object sender, EventArgs eventArgs)
- {
- var timer = (System.Timers.Timer)sender;
- test++;
- ScreenCapture(cdr_run);
- if (test == 1000)
- {
- timer.Stop();
- MessageBox.Show(sw.ElapsedMilliseconds.ToString() + " / " + test.ToString());
- sw.Reset();
- }
- //if (test < 1000) timer.Start();
- }
Решение задачи: «System.Timers.Timer и Lock»
textual
Листинг программы
- private static readonly Stopwatch TestStopwatch = new Stopwatch();
- private static int _counter;
- private void button1_Click(object sender, EventArgs e)
- {
- var timerTest = new System.Timers.Timer
- {
- AutoReset = false,
- Interval = 100
- };
- _counter = 0;
- timerTest.Elapsed += timerTest_Elapsed;
- timerTest.Enabled = true;
- }
- private static void timerTest_Elapsed(object sender, EventArgs e)
- {
- var timerTest = (System.Timers.Timer)sender;
- _counter++;
- try
- {
- if (!TestStopwatch.IsRunning)
- TestStopwatch.Start();
- }
- catch
- {
- //ignore
- }
- finally
- {
- if (_counter > 10)
- MessageBox.Show(@"Времени прошло за " + (_counter - 1) + @" кругов по " + timerTest.Interval + @"мс: " + TestStopwatch.ElapsedMilliseconds);
- else
- {
- TestStopwatch.Reset();
- timerTest.Enabled = true;
- }
- }
- }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д