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; } } }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д