4

Windows フォームでスレッドの終了に問題があります。

実行中の従来の Windows フォームがあります。毎回何かをする必要があるので、次のように追加しました。

TimerCallback timerDelegate = new TimerCallback(this.TryDoSomething);
int period = 10 * 1000; // to miliseconds
System.Threading.Timer stateTimer = new System.Threading.Timer(timerDelegate, null, period, period);

メソッド DoSomething はいくつかのスレッド (メイン スレッドとこのタイマー) によって呼び出されるので、そのようにカバーしました。

private void TryDoSomething(object o)
        {
            lock (tryDoSomethingMutex)
            {
                if (this.dataGridView1.InvokeRequired)
                {
                    RefreshCallback d = new RefreshCallback(DoSomething);
                    this.Invoke(d, new object[] { o });
                }
                else
                {
                    this.DoSomething(o);
                } 
            }
        }

そして、私のタイマースレッドがメッセージで終了するまで、すべてがうまくいきます:

The thread 0x2798 has exited with code 0 (0x0).

DoSomething メソッドも呼び出す FileSystemWatcher でも同じことが起こります。両方のイベントは独立しており、ランダムな時間に終了します (少なくとも、ルールは見つかりませんでした)。

この状況の原因は何ですか?どうすれば回避できますか?

4

2 に答える 2

4

タイマー オブジェクトへの参照を保持しないと、ガベージ コレクションが実行されます。

投稿したコードを見ると、参照を保持しているようには見えません。ローカル変数ではなく、含まれているクラスのフィールドにする必要があります。

長時間実行されるメソッドの開始時にタイマーを宣言し、後でメソッド内で参照しない場合、タイマーもガベージ コレクションされる可能性があります。

here で説明されているようGC.KeepAlive(timer);に、メソッドの最後近くに追加することで、その特定の問題を修正できます。

于 2013-04-17T08:07:08.410 に答える
3

タイマーがガベージコレクションを取得しているようです。参照を保持できるように、フォームのインスタンス変数にします。

于 2013-04-17T08:06:26.470 に答える