編集:私の最初の答えはゴミです。本当にゴミ。なぜゴミなのかを説明するためにここに残しておきました-コメントにありますが、答えがあれば削除されていたはずです。
GC.KeepAlive は、呼び出し後まで参照がルートとして扱われることを確認するだけです。この回答の下部にあるコードでは、GC.KeepAlive メソッドがすぐに呼び出され、タイマーは引き続きガベージ コレクションの対象になります。新しく作成されたスレッドはフォアグラウンド スレッドであるため、アプリはそれが存続している限り実行されます (一方、タイマーはプログラムの終了を妨げないバックグラウンド スレッドを使用します)。これは、Main メソッドは終了しますが、アプリケーションは実行し続ける必要があることを意味します。
おそらく、新しいスレッドを作成してからメイン スレッドを終了させるよりも、メイン スレッドで実行する方が簡単な解決策になるでしょう。myThreadStart
つまり、簡単な解決策は次のようになります。
using System.Threading;
class Program {
static void Main() {
Timer timer = new Timer(myTimerCallback,
new MyStateObject(), 0, 5000);
myThreadStart();
GC.KeepAlive(timer);
}
}
ただし、実際のコードはもっと複雑だと思います-その場合、他の回答で提案されているようにプライベート静的変数を使用するのがおそらく道です。使い方にもよるだろうけど。個人的には、代替手段 (上記のような) がある場合に何かが収集されるのを防ぐためだけに静的フィールドを作成しないことを好みますが、それが事実上唯一の方法である場合もあります。
元の(悪い)答え:
本当にメインに割り当てたい場合は、GC.KeepAliveを使用できます。
using System.Threading;
class Program {
static void Main() {
new Thread(myThreadStart).Start();
Timer timer = new Timer(myTimerCallback,
new MyStateObject(), 0, 5000);
GC.KeepAlive(timer);
}
}