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;
}
}
}