System.Threading.Timer が勝手に停止するのはなぜですか? 質問する

System.Threading.Timer が勝手に停止するのはなぜですか? 質問する

Windows サービス プロジェクトで使用する前に、小さなテスト プロジェクトを実行していますSystem.Threading.Timer。 問題なく動作していますが、1 ~ 2 分後にタイマーが自動的に停止します。

テスト プロジェクトの完全なソースは次のとおりです。

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

目標は明らかに、ラベルを現在の時刻で更新することです。しばらくすると更新が停止することに気づきました。これはなぜでしょうか?

ベストアンサー1

Windows フォームでタイマーが必要な場合は、フォームに をドロップします。55ミリ秒よりも高い解像度が必要でない限り、System.Windows.Forms.Timerを使用する理由はありません。System.Threading.Timer

タイマーが「停止」する理由は、ガベージ コレクションされているためです。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

おすすめ記事