1つの違いは、System.Threading.Timer
毎回新しいスレッドを作成するのではなく、スレッドプールスレッドにコールバックをディスパッチすることです。アプリケーションの存続期間中にこれを複数回発生させる必要がある場合は、スレッドの束を作成および破棄するオーバーヘッドを節約できます(参照する記事で指摘されているように、非常にリソースを消費するプロセスです)。プール内のスレッドを再利用するだけで、一度に複数のタイマーを実行する場合は、一度に実行するスレッドが少なくなることを意味します(また、かなりのリソースを節約できます)。
言い換えれば、Timer
はるかに効率的になります。また、Thread.Sleep
指定した時間だけ待機することが保証されているため、より正確な場合があります(OSはそれをはるかに長くスリープ状態にする可能性があります)。確かに、Timer
それでも正確にはなりませんが、コールバックを指定された時間にできるだけ近づけることを目的としていますが、これは必ずしもの目的ではありませんThread.Sleep
。
を破棄することTimer
に関しては、コールバックはパラメーターを受け入れることができるので、Timer
それ自体をパラメーターとして渡し、コールバックでDisposeを呼び出すことができる場合があります(これは試していませんが、タイマーがコールバック中にロックされます)。
Timer
編集:いいえ、コンストラクター自体でコールバックパラメーターを指定する必要があるため、これはできないと思います。
多分このようなもの?(繰り返しますが、実際に試したことはありません)
class TimerState
{
public Timer Timer;
}
...そしてタイマーを開始するには:
TimerState state = new TimerState();
lock (state)
{
state.Timer = new Timer((callbackState) => {
action();
lock (callbackState) { callbackState.Timer.Dispose(); }
}, state, millisecond, -1);
}
Timer
ロックにより、フィールドが設定される前にタイマーコールバックがタイマーを解放しようとするのを防ぐ必要があります。
補遺:コメント投稿者が指摘したaction()
ように、UIで何かを行う場合はSystem.Windows.Forms.Timer
、UIスレッドでコールバックを実行するため、おそらくaを使用する方が適切です。ただし、これが当てはまらず、Thread.Sleep
vs 。にかかっている場合はThreading.Timer
、それが最善Threading.Timer
の方法です。