2011-02-10 27 views
3

これは、System.Timers.Timerを使用する正しい方法ですか? 私はタイマーを作成し、Elapsedイベントで呼び出される間隔とメソッドを設定します。System.Timers.Timerライフサイクル

double ms = 1000; 
var t = new System.Timers.Timer(ms); 
t.AutoReset = false; 
t.Elapsed += (sender, e) => { runTask(); }; 
t.Start(); 

次は何ですか?タイマーでコールを処分する必要がありますか?私はできないと思う、またはElapsedイベントは起こりません。 Timerをグローバル変数に登録して、参照を失わないようにする必要があります。そのため、Elapsedが呼び出される前にGCがタイマーを破棄することができますか? もしそうなら、Elapsedイベントが処理された(つまり、タスクが実行された)ときに、どのようにTimerを処分できますか?

答えて

1

簡単な答えは何もする必要がないということです。機能が範囲外になると、ガベージコレクタによって収集されます。それを利用できるようにしたい場合は、代わりにクラスで宣言してください。


通常、クラスレベルでタイマーを宣言すると、クラスが廃棄されたときにGCによってタイマーが収集されます。あなたが機能であなたのタイマー宣言を持っている場合しかし、その後、タイマーがまだ実行されますが、あなたは非常に長いプロセスを実行している場合は、の終わりを見てください

GC.KeepAlive(youtimer_Instance); 

を使用する必要がありますので、その後、GCは、積極的にそれを配置することができますこのシナリオを参照するためにTimer's Documentatio n。

サンプルコード内のコメントは述べています:


     Normally, the timer is declared at the class level, 
     so that it stays in scope as long as it is needed. 
     If the timer is declared in a long-running method, 
     KeepAlive must be used to prevent the JIT compiler 
     from allowing aggressive garbage collection to occur 
     before the method ends. 
+0

これは、タイマーがフォームAで作成され、ユーザーがアプリケーションを終了した場合(タスクがフォームコントロールにアクセスしようとしていると例外が発生します。 –

+0

@Mohib Sheth:私が答えたのは、タイマーが破棄されるのを防ぐ方法です。停止するには、Stop()を呼び出す必要があります。必要に応じてイベントハンドラの登録を解除することができればさらに優れています。 Alexisはそれを説明しました.... –

+0

あなたが引用したコードコメントは、Timerのドキュメントにはもう存在しません。 –

0

フォーム/ページの任意の場所または近くにあるClose/Unloadでt.Stop()を呼び出す必要があります。実行中のままにすると、不必要にリソースが活用され、アプリケーションを終了する際に例外が発生する可能性があります。

4

あなたがメモリを取得したくない場合は、長時間実行されるプロセス(例えば、WebアプリケーションまたはWindowsサービス)の間にタイマーを使用している場合ガーベッジコレクタがTimerオブジェクトに割り当てられたメモリを再利用できるようにするには、Timerの経過イベントハンドラの登録を解除する必要があります。

System.Timers.TimerはIDisposableを実装しており、IDisposableを実装するクラスがある場合、IDisposableを実装しているオブジェクトに依存するすべてのクラスでIDisposable自体を実装し、Dispose()メソッドを呼び出す必要があります。それ自体が呼び出されます。

これの完璧な例は確かにSystem.Timers.Timerです。これは、カバーの下にSystem.Threading.Timerを使用して、反射鏡で見れば、あなたがここで

public void Dispose() 
{ 
    this.timerBase.Dispose(); 
} 

でSystem.Timers.Timer

にDisposeメソッドについては、以下を参照することができ、timerBaseは単にSystem.Threadingのインスタンスです。 Timer、したがってDisposeコールは、IDisposableを実装するクラスのすべての依存関係にカスケードします。

+0

+1購読不要のニーズを指摘するため – themarcuz