System.Timers.Timer и Lock - C#

Узнай цену своей работы

Формулировка задачи:

Добрый день. Почитал немного про Thread Safety, про ThreadPool, про синхронизацию потоков. Но всё равно что-то не сходится, потому прошу пояснить, если возможно.

Вопрос:

Как именно работает System.Timers.Timer в плане создания потоков?

Сделал простой код. Нажимаю кнопку, запускаю таймер с интервалом 1 мс. Внутри выполняется функция ScreenCapture, которая (по результатам теста) выполняется где-то 15 мс. Как я думал, потоки будут перекрывать друг друга и нужна будет блокировка или какая-то другая синхронизация. Использовал lock, использовал Monitor.TryEnter (с разными значениями), использовал AutoReset = false. Удивительно, что в любом варианте вывод на экран был одинаковый с небольшими колебаниями ("15600 / 1000"). Получается, что следующий поток таймера всё-таки ждёт окончания предыдущего и никакие локи не нужны? На форумах нашёл очень много про блокировки в таймерах, везде советуют их использовать. Почему так получается?
Листинг программы
  1. private void button1_Click(object sender, EventArgs e)
  2. {
  3. test = 0;
  4. System.Timers.Timer test_timer = new System.Timers.Timer();
  5. test_timer.Interval = 1;
  6. test_timer.Elapsed += test_timer_Tick;
  7. //test_timer.AutoReset = false;
  8. sw = new Stopwatch();
  9. sw.Start();
  10. test_timer.Start();
  11. }
  12. public void test_timer_Tick(object sender, EventArgs eventArgs)
  13. {
  14. var timer = (System.Timers.Timer)sender;
  15. test++;
  16. ScreenCapture(cdr_run);
  17. if (test == 1000)
  18. {
  19. timer.Stop();
  20. MessageBox.Show(sw.ElapsedMilliseconds.ToString() + " / " + test.ToString());
  21. sw.Reset();
  22. }
  23. //if (test < 1000) timer.Start();
  24. }

Решение задачи: «System.Timers.Timer и Lock»

textual
Листинг программы
  1.         private static readonly Stopwatch TestStopwatch = new Stopwatch();
  2.         private static int _counter;
  3.  
  4.         private void button1_Click(object sender, EventArgs e)
  5.         {
  6.             var timerTest = new System.Timers.Timer
  7.             {
  8.                 AutoReset = false,
  9.                 Interval = 100
  10.             };
  11.             _counter = 0;
  12.             timerTest.Elapsed += timerTest_Elapsed;
  13.             timerTest.Enabled = true;
  14.         }
  15.  
  16.  
  17.         private static void timerTest_Elapsed(object sender, EventArgs e)
  18.         {
  19.             var timerTest = (System.Timers.Timer)sender;
  20.             _counter++;
  21.  
  22.             try
  23.             {
  24.                 if (!TestStopwatch.IsRunning)
  25.                     TestStopwatch.Start();
  26.             }
  27.             catch
  28.             {
  29.                 //ignore
  30.             }
  31.             finally
  32.             {
  33.                 if (_counter > 10)
  34.                     MessageBox.Show(@"Времени прошло за " + (_counter - 1) + @" кругов по " + timerTest.Interval + @"мс: " + TestStopwatch.ElapsedMilliseconds);
  35.                 else
  36.                 {
  37.                     TestStopwatch.Reset();
  38.                     timerTest.Enabled = true;
  39.                 }
  40.             }
  41.         }

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

6   голосов , оценка 4 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут