Почему System.Threading.Timer останавливается сам по себе? - PullRequest
17 голосов
/ 04 февраля 2010

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

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

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

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

Ответы [ 3 ]

37 голосов
/ 04 февраля 2010

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

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

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

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 голос
/ 22 августа 2014

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

0 голосов
/ 04 февраля 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...