Почему System.Threading.Timer останавливается самостоятельно?

Вопрос:Я делаю небольшой тестовый проект, прежде чем использовать System.Threading.Timer в проекте Windows Service. Он работает чудесно, однако таймер останавливается сам по себе через минуту или две. Полный источник тестового проекта: using System; using System.Windows.Forms; using System.Threading; namespace studyTimers { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender,

Вопрос:

Я делаю небольшой тестовый проект, прежде чем использовать System.Threading.Timer в проекте Windows Service. Он работает чудесно, однако таймер останавливается сам по себе через минуту или две.

Полный источник тестового проекта:

using System; using System.Windows.Forms; using System.Threading; namespace studyTimers { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { TimerCallback timerDelegate = new TimerCallback(tick); System.Threading.Timer testTimer = new System.Threading.Timer(timerDelegate, null, 1000, 1000); } void tick(Object obj) { if (label1.InvokeRequired) { label1.Invoke(new MethodInvoker(() => tick(obj))); } else { label1.Text = DateTime.Now.ToString(); } } } }

Целью является, очевидно, обновление метки с текущим временем. Я замечаю, что обновление останавливается немного. Почему это должно быть?

Лучший ответ:

Если вам нужен таймер в Windows Form, то оставьте System.Windows.Forms.Timer на форму – нет причин использовать System.Threading.Timer, если вам не требуется лучшее разрешение, чем 55 мс.

Причина, по которой таймер “останавливается”, заключается в том, что он собирает мусор. Вы разрешаете ему выйти из области видимости в методе Form1_Load, потому что вы объявляете его только как локальную переменную. Чтобы сохранить таймер “живой”, он должен быть частным полем класса формы, чтобы GC знал, что он все еще нужен.

Другими словами:

public partial class Form1 : Form { private System.Threading.Timer testTimer; … public void Form1_Load(object sender, EventArgs e) { TimerCallback timerDelegate = new TimerCallback(tick); testTimer = new System.Threading.Timer(timerDelegate, null, 1000, 1000); } }

Но опять же, в этом случае проще использовать System.Windows.Forms.Timer, который является фактическим компонентом в панели инструментов, который вы можете просто добавить в форму.

Изменить. Как теперь показывают комментарии, если это просто тестовое приложение, а реальное приложение находится в службе Windows, вы не можете использовать для этого System.Windows.Forms.Timer. Просто не забывайте, чтобы ваш System.Threading.Timer вышел из сферы действия.

Ответ №1

Сборщик мусора собрал объект таймера, вы должны сохранить ссылку на него.
этот пост поможет: http://msdn.microsoft.com/en-us/library/system.threading.timer.aspx

Ответ №2

Не следует. Есть ли проблема с вашим кодом?
Изменить: Я говорил о таймере, который находится в панели инструментов.

Оцените статью
Добавить комментарий