Timer.Stop メソッド
アセンブリ: System (system.dll 内)


Enabled を false に設定すると、タイマのカウントも停止できます。
![]() |
---|
Elapsed イベントは ThreadPool スレッドで発生するため、1 つのスレッドでイベント処理を実行する間に、Stop メソッドの呼び出しが別のスレッドで実行されることがあります。これにより、Stop メソッドを呼び出した後で、Elapsed イベントが発生することがあります。このトピックのコード例では、この競合状態を回避する方法の一例を示しています。 |

実行中の Elapsed イベントが終了するまで Stop メソッドを呼び出すスレッドを継続しないようにする方法、および 2 つの Elapsed イベントがイベント ハンドラを同時に実行する状況 (再入ともいう) が発生しないようにする方法を、次のコード例に示します。
この例では、テストを 100 回実行します。テストを実行するたびに、150 ミリ秒の間隔を設定したタイマが開始されます。イベント ハンドラは Thread.Sleep メソッドを使用して、長さが 50 ~ 200 ミリ秒の範囲でランダムに変化するタスクをシミュレートします。また、テスト メソッドは、1 秒待機してからタイマを停止するコントロール スレッドも開始します。タイマの停止時にイベントが処理中である場合は、コントロール スレッドはイベントが終了するまで待ち、それから処理を継続する必要があります。
再入を防ぎ、イベントが終了するまでコントロール スレッドが処理を継続できないようにするために、Interlocked.CompareExchange(Int32,Int32,Int32) メソッドのオーバーロードを使用しています。イベント ハンドラは CompareExchange(Int32,Int32,Int32) メソッドを使用して、コントロール変数を 1 に設定します (現在の値がゼロの場合のみ)。これは分割不可能な操作です。戻り値がゼロの場合、コントロール変数は 1 に設定されており、イベント ハンドラは処理を続けます。戻り値がゼロ以外の場合は、再入を避けるためにイベントを単に破棄します(すべてのイベントを実行する必要がある場合は、Monitor クラスを使用してイベントを同期する方法をお勧めします)。イベント ハンドラが終了するとき、コントロール変数をゼロに戻します。この例では、実行したイベントの総数、再入により破棄したイベントの総数、および Stop メソッドの呼び出し後に発生したイベントの総数を記録しています。
コントロール スレッドは CompareExchange(Int32,Int32,Int32) メソッドを使用して、コントロール変数を -1 (マイナス 1) に設定します (現在の値がゼロの場合のみ)。分割不可能な操作からの戻り値がゼロ以外の場合は、イベントが実行中です。コントロール スレッドはしばらく待機してから、再試行します。この例では、イベントが終了するまでコントロール スレッドが待機した回数の総数を記録しています。
Imports System Imports System.Timers Imports System.Threading Public Module Test ' Change these values to control the behavior of the program. Private testRuns As Integer = 100 ' Times are given in milliseconds: Private testRunsFor As Integer = 1000 Private timerInterval As Integer = 150 ' Qualify the name to avoid confusion with the ' System.Threading.Timer class. Private WithEvents Timer1 As New System.Timers.Timer Private rand As New Random() ' This is the synchronization point that prevents events ' from running concurrently, and prevents the main thread ' from executing code after the Stop method until any ' event handlers are done executing. Private syncPoint As Integer = 0 ' Count the number of times the event handler is called, ' is executed, is skipped, or is called after Stop. Private numEvents As Integer = 0 Private numExecuted As Integer = 0 Private numSkipped As Integer = 0 Private numLate As Integer = 0 ' Count the number of times the thread that calls Stop ' has to wait for an Elapsed event to finish. Private numWaits As Integer = 0 <MTAThread> _ Sub Main() Timer1.Interval = timerInterval Console.WriteLine() For i As Integer = 1 To testRuns TestRun Console.Write(vbCr & "Test {0}/{1} ", i, testRuns) Next Console.WriteLine("{0} test runs completed.", testRuns) Console.WriteLine("{0} events were raised.", numEvents) Console.WriteLine("{0} events executed.", numExecuted) Console.WriteLine("{0} events were skipped for concurrency.", numSkipped) Console.WriteLine("{0} events were skipped because they were late.", numLate) Console.WriteLine("Control thread waited {0} times for an event to complete.", numWaits) End Sub Sub TestRun() ' Set syncPoint to zero before starting the test ' run. syncPoint = 0 Timer1.Enabled = True ' Start the control thread that shuts off the timer. Dim t As New Thread(AddressOf ControlThreadProc) t.Start() ' Wait until the control thread is done before proceeding. ' This keeps the test runs from overlapping. t.Join() End Sub Private Sub ControlThreadProc() ' Allow the timer to run for a period of time, and then ' stop it. Thread.Sleep(testRunsFor) Timer1.Stop ' The 'counted' flag ensures that if this thread has ' to wait for an event to finish, the wait only gets ' counted once. Dim counted As Boolean = False ' Ensure that if an event is currently executing, ' no further processing is done on this thread until ' the event handler is finished. This is accomplished ' by using CompareExchange to place -1 in syncPoint, ' but only if syncPoint is currently zero (specified ' by the third parameter of CompareExchange). ' CompareExchange returns the original value that was ' in syncPoint. If it was not zero, then there's an ' event handler running, and it is necessary to try ' again. While Interlocked.CompareExchange(syncPoint, -1, 0) <> 0 ' Give up the rest of this thread's current time ' slice. This is a fairly naive algorithm for ' yielding. Thread.Sleep(0) ' Tally a wait, but don't count multiple calls to ' Thread.Sleep. If Not counted Then numWaits += 1 counted = True End If End While ' Any processing done after this point does not conflict ' with timer events. This is the purpose of the call to ' CompareExchange. If the processing done here would not ' cause a problem when run concurrently with timer events, ' then there is no need for the extra synchronization. End Sub ' Event-handling methof for the Elapsed event. Private Sub Timer1_ElapsedEventHandler( _ ByVal sender As Object, _ ByVal e As ElapsedEventArgs _ ) Handles Timer1.Elapsed numEvents += 1 ' This example assumes that overlapping events can be ' discarded. That is, if an Elapsed event is raised before ' the previous event is finished processing, the second ' event is ignored. ' ' CompareExchange is used to take control of syncPoint, ' and to determine whether the attempt was successful. ' CompareExchange attempts to put 1 into syncPoint, but ' only if the current value of syncPoint is zero ' (specified by the third parameter). If another thread ' has set syncPoint to 1, or if the control thread has ' set syncPoint to -1, the current event is skipped. ' (Normally it would not be necessary to use a local ' variable for the return value. A local variable is ' used here to determine the reason the event was ' skipped.) ' Dim sync As Integer = Interlocked.CompareExchange(syncPoint, 1, 0) If sync = 0 Then ' No other event was executing. ' The event handler simulates an amount of work ' lasting between 50 and 200 milliseconds, so that ' some events will overlap. Dim delay As Integer = 50 + rand.Next(150) Thread.Sleep(delay) numExecuted += 1 ' Release control of syncPoint. syncPoint = 0 Else If sync = 1 Then numSkipped += 1 Else numLate += 1 End If End Sub End Module ' On a dual-processor computer, this code example produces ' results similar to the following: ' 'Test 100/100 100 test runs completed. '600 events were raised. '488 events executed. '112 events were skipped for concurrency. '0 events were skipped because they were late. 'Control thread waited 73 times for an event to complete.
using System; using System.Timers; using System.Threading; public class Test { // Change these values to control the behavior of the program. private static int testRuns = 100; // Times are given in milliseconds: private static int testRunsFor = 1000; private static int timerInterval = 150; // Qualify the name to avoid confusion with the // System.Threading.Timer class. private static System.Timers.Timer Timer1 = new System.Timers.Timer(); private static Random rand = new Random(); // This is the synchronization point that prevents events // from running concurrently, and prevents the main thread // from executing code after the Stop method until any // event handlers are done executing. private static int syncPoint = 0; // Count the number of times the event handler is called, // is executed, is skipped, or is called after Stop. private static int numEvents = 0; private static int numExecuted = 0; private static int numSkipped = 0; private static int numLate = 0; // Count the number of times the thread that calls Stop // has to wait for an Elapsed event to finish. private static int numWaits = 0; [MTAThread] public static void Main() { Timer1.Elapsed += new ElapsedEventHandler(Timer1_ElapsedEventHandler); Timer1.Interval = timerInterval; Console.WriteLine(); for(int i = 1; i <= testRuns; i++) { TestRun(); Console.Write("\rTest {0}/{1} ", i, testRuns); } Console.WriteLine("{0} test runs completed.", testRuns); Console.WriteLine("{0} events were raised.", numEvents); Console.WriteLine("{0} events executed.", numExecuted); Console.WriteLine("{0} events were skipped for concurrency.", numSkipped); Console.WriteLine("{0} events were skipped because they were late.", numLate); Console.WriteLine("Control thread waited {0} times for an event to complete.", numWaits); } public static void TestRun() { // Set syncPoint to zero before starting the test // run. syncPoint = 0; Timer1.Enabled = true; // Start the control thread that shuts off the timer. Thread t = new Thread(ControlThreadProc); t.Start(); // Wait until the control thread is done before proceeding. // This keeps the test runs from overlapping. t.Join(); } private static void ControlThreadProc() { // Allow the timer to run for a period of time, and then // stop it. Thread.Sleep(testRunsFor); Timer1.Stop(); // The 'counted' flag ensures that if this thread has // to wait for an event to finish, the wait only gets // counted once. bool counted = false; // Ensure that if an event is currently executing, // no further processing is done on this thread until // the event handler is finished. This is accomplished // by using CompareExchange to place -1 in syncPoint, // but only if syncPoint is currently zero (specified // by the third parameter of CompareExchange). // CompareExchange returns the original value that was // in syncPoint. If it was not zero, then there's an // event handler running, and it is necessary to try // again. while (Interlocked.CompareExchange(ref syncPoint, -1, 0) != 0) { // Give up the rest of this thread's current time // slice. This is a fairly naive algorithm for // yielding. Thread.Sleep(0); // Tally a wait, but don't count multiple calls to // Thread.Sleep. if (!counted) { numWaits += 1; counted = true; } } // Any processing done after this point does not conflict // with timer events. This is the purpose of the call to // CompareExchange. If the processing done here would not // cause a problem when run concurrently with timer events, // then there is no need for the extra synchronization. } // Event-handling method for the Elapsed event. private static void Timer1_ElapsedEventHandler( object sender, ElapsedEventArgs e) { numEvents += 1; // This example assumes that overlapping events can be // discarded. That is, if an Elapsed event is raised before // the previous event is finished processing, the second // event is ignored. // // CompareExchange is used to take control of syncPoint, // and to determine whether the attempt was successful. // CompareExchange attempts to put 1 into syncPoint, but // only if the current value of syncPoint is zero // (specified by the third parameter). If another thread // has set syncPoint to 1, or if the control thread has // set syncPoint to -1, the current event is skipped. // (Normally it would not be necessary to use a local // variable for the return value. A local variable is // used here to determine the reason the event was // skipped.) // int sync = Interlocked.CompareExchange(ref syncPoint, 1, 0); if (sync == 0) { // No other event was executing. // The event handler simulates an amount of work // lasting between 50 and 200 milliseconds, so that // some events will overlap. int delay = 50 + rand.Next(150); Thread.Sleep(delay); numExecuted += 1; // Release control of syncPoint. syncPoint = 0; } else { if (sync == 1) { numSkipped += 1; } else { numLate += 1; } } } } /* On a dual-processor computer, this code example produces results similar to the following: Test 100/100 100 test runs completed. 600 events were raised. 488 events executed. 112 events were skipped for concurrency. 0 events were skipped because they were late. Control thread waited 73 times for an event to complete. */

Windows 98, Windows 2000 SP4, Windows Millennium Edition, Windows Server 2003, Windows XP Media Center Edition, Windows XP Professional x64 Edition, Windows XP SP2, Windows XP Starter Edition
開発プラットフォームの中には、.NET Framework によってサポートされていないバージョンがあります。サポートされているバージョンについては、「システム要件」を参照してください。


Timer.Stop メソッド
アセンブリ: System.Windows.Forms (system.windows.forms.dll 内)


Enabled プロパティを false に設定して、タイマを停止することもできます。Timer オブジェクトは、同じアプリケーションのセッション内で複数回にわたって有効または無効にできます。
Stop を呼び出して Timer を無効にした後に Start を呼び出すと、Timer は中断された間隔を再開します。たとえば、Timer が 5000 ミリ秒の間隔に設定されているときに約 3000 ミリ秒の時点で Stop を呼び出した場合、Start を呼び出すと、Timer は 5000 ミリ秒待機してから Tick イベントを発生させます。
![]() |
---|
すべての Timer コンポーネントはメインのアプリケーション スレッド上で動作するため、Windows フォーム アプリケーション内のいずれかの Timer に対して Stop を呼び出すと、アプリケーション内の直ちに処理する必要のある他の Timer コンポーネントからメッセージが表示される場合があります。たとえば、2 つの Timer コンポーネントがあり、1 つは 700 ミリ秒、もう 1 つは 500 ミリ秒に設定されている場合、1 つ目の Timer に対して Stop を呼び出すと、2 つ目のコンポーネントのイベント コールバックが先に受信される場合があります。この動作によって問題が生じる場合は、System.Threading 名前空間の Timer クラスを使用します。 |

5 秒ごとにアラームを発生させる単純な間隔タイマを実装するコード例を次に示します。アラームが発生すると、MessageBox にアラームが起動した回数が表示され、タイマの実行を継続するかどうかをユーザーに問い合わせるメッセージが表示されます。
Public Class Class1 Private Shared myTimer As New System.Windows.Forms.Timer() Private Shared alarmCounter As Integer = 1 Private Shared exitFlag As Boolean = False ' This is the method to run when the timer is raised. Private Shared Sub TimerEventProcessor(myObject As Object, _ myEventArgs As EventArgs) myTimer.Stop() ' Displays a message box asking whether to continue running the timer. If MessageBox.Show("Continue running?", "Count is: " & alarmCounter, _ MessageBoxButtons.YesNo) = DialogResult.Yes Then ' Restarts the timer and increments the counter. alarmCounter += 1 myTimer.Enabled = True Else ' Stops the timer. exitFlag = True End If End Sub Public Shared Sub Main() ' Adds the event and the event handler for the method that will ' process the timer event to the timer. AddHandler myTimer.Tick, AddressOf TimerEventProcessor ' Sets the timer interval to 5 seconds. myTimer.Interval = 5000 myTimer.Start() ' Runs the timer, and raises the event. While exitFlag = False ' Processes all the events in the queue. Application.DoEvents() End While End Sub End Class
public class Class1 { static System.Windows.Forms.Timer myTimer = new System.Windows.Forms.Timer(); static int alarmCounter = 1; static bool exitFlag = false; // This is the method to run when the timer is raised. private static void TimerEventProcessor(Object myObject, EventArgs myEventArgs) { myTimer.Stop(); // Displays a message box asking whether to continue running the timer. if(MessageBox.Show("Continue running?", "Count is: " + alarmCounter, MessageBoxButtons.YesNo) == DialogResult.Yes) { // Restarts the timer and increments the counter. alarmCounter +=1; myTimer.Enabled = true; } else { // Stops the timer. exitFlag = true; } } public static int Main() { /* Adds the event and the event handler for the method that will process the timer event to the timer. */ myTimer.Tick += new EventHandler(TimerEventProcessor); // Sets the timer interval to 5 seconds. myTimer.Interval = 5000; myTimer.Start(); // Runs the timer, and raises the event. while(exitFlag == false) { // Processes all the events in the queue. Application.DoEvents(); } return 0; } }
public ref class Class1 { private: static System::Windows::Forms::Timer^ myTimer = gcnew System::Windows::Forms::Timer; static int alarmCounter = 1; static bool exitFlag = false; // This is the method to run when the timer is raised. static void TimerEventProcessor( Object^ /*myObject*/, EventArgs^ /*myEventArgs*/ ) { myTimer->Stop(); // Displays a message box asking whether to continue running the timer. if ( MessageBox::Show( "Continue running?", String::Format( "Count is: {0}", alarmCounter ), MessageBoxButtons::YesNo ) == DialogResult::Yes ) { // Restarts the timer and increments the counter. alarmCounter += 1; myTimer->Enabled = true; } else { // Stops the timer. exitFlag = true; } } public: static void Main() { /* Adds the event and the event handler for the method that will process the timer event to the timer. */ myTimer->Tick += gcnew EventHandler( TimerEventProcessor ); // Sets the timer interval to 5 seconds. myTimer->Interval = 5000; myTimer->Start(); // Runs the timer, and raises the event. while ( exitFlag == false ) { // Processes all the events in the queue. Application::DoEvents(); } } }; int main() { Class1::Main(); }
public class Class1 { private static System.Windows.Forms.Timer myTimer = new System.Windows.Forms.Timer(); private static int alarmCounter = 1; private static boolean exitFlag = false; // This is the method to run when the timer is raised. private static void TimerEventProcessor(Object myObject, EventArgs myEventArgs) { myTimer.Stop(); // Displays a message box asking whether to continue running the timer. if (MessageBox.Show("Continue running?", "Count is: " + alarmCounter, MessageBoxButtons.YesNo).Equals(DialogResult.Yes)) { // Restarts the timer and increments the counter. alarmCounter += 1; myTimer.set_Enabled(true); } else { // Stops the timer. exitFlag = true; } } //TimerEventProcessor public static void main(String[] args) { /* Adds the event and the event handler for the method that will process the timer event to the timer. */ myTimer.add_Tick(new EventHandler(TimerEventProcessor)); // Sets the timer interval to 5 seconds. myTimer.set_Interval(5000); myTimer.Start(); // Runs the timer, and raises the event. while (exitFlag == false) { // Processes all the events in the queue. Application.DoEvents(); } return; } //main } //Class1

Windows 98, Windows 2000 SP4, Windows CE, Windows Millennium Edition, Windows Mobile for Pocket PC, Windows Mobile for Smartphone, Windows Server 2003, Windows XP Media Center Edition, Windows XP Professional x64 Edition, Windows XP SP2, Windows XP Starter Edition
開発プラットフォームの中には、.NET Framework によってサポートされていないバージョンがあります。サポートされているバージョンについては、「システム要件」を参照してください。


Weblioに収録されているすべての辞書からTimer.Stopを検索する場合は、下記のリンクをクリックしてください。

- Timer.Stopのページへのリンク