質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

1回答

8556閲覧

C# タイマー処理を停止したい

warks1

総合スコア12

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

0クリップ

投稿2018/11/16 01:36

編集2018/11/16 03:19

開発環境:visual studio 2017

現在、タイマー処理を利用して一定時間毎にループする処理を実装したいのですが、苦戦しています。
苦戦している点は、停止時にFormは消さずに処理のみ停止させたいです。
現状は下記で記載しています。停止ボタンを押すとアプリケーションごと終了させてしまっています。

希望としては、
①Formを消さずにループ処理のみ終了させたい
②いつでもボタンを押せば停止するようにしたい。
③再度、実行するときは最初からスタートしたい
です。

タイマーの種類も多く存在しており、いろいろなサイトを見ても理解出来ていません。
下記のソースを使ってこんな感じに記載すればよいと教えていただけると理解して今後に生かせると思っていますのでお手数をおかけ致しますが回答お願いいたします。

C#

1public partial class Form1 : Form 2 { 3 System.Windows.Forms.Timer timer1 = new System.Windows.Forms.Timer(); 4 System.Windows.Forms.Timer timer2 = new System.Windows.Forms.Timer(); 5 loop1(Main_loop); 6 loop2(sabu_loop); 7 public Form1() 8 { 9 InitializeComponent(); 10 button1.Enabled = true; 11 button2.Enabled = false; 12 } 13 public void button1_Click(object sender, EventArgs e) 14 { 15 button1.Enabled = false; 16 button2.Enabled = true; 17 18 //タイマー開始 19 timer1.Enabled = true; 20 timer2.Enabled = true; 21 } 22 private void button2_Click(object sender, EventArgs e) 23 { 24 //タイマーの停止 25 timer1.Enabled = false; 26 timer2.Enabled = false; 27 //ボタンを戻す 28 button1.Enabled = true; 29 button2.Enabled = false; 30 } 31 32 //3秒ごとに動くタイマー 33 public void loop1(EventHandler eventHandler) 34 { 35 timer1.Tick += new EventHandler(eventHandler); 36 timer1.Interval = 1000; 37 timer1.Enabled = false; 38 39 } 40 //numericUpDown1 * 60秒 でループするタイマー 41 public void loop2(EventHandler eventHandler) 42 { 43 int intVal = Decimal.ToInt32(numericUpDown1.Value); 44 timer2.Tick += new EventHandler(eventHandler); 45 timer2.Interval = intVal * 60000; 46 timer2.Enabled = false; 47 } 48 private void Main_loop(object sender, EventArgs e) 49 { 50 //メイン処理 51 } 52 void sabu_loop(object sender, EventArgs e) 53 { 54 //サブ処理 55 } 56 57 } 58} 59

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

C#

1//loopの中ではなく、クラス内で使用できるスコープで宣言する 2System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer(); 3 4 private void button2_Click(object sender, EventArgs e) 5 { 6 //タイマーの停止 7 timer.Enabled = false; 8 //ボタンを戻す 9 button1.Enabled = true; 10 button2.Enabled = false; 11 12 } 13

でタイマーの停止はできるかと
再開に関してはMain_loop内の処理次第でしょう。
フラグなり設けるか、して最初から行えばいいでしょう。

また、loop内でTimerの生成、イベントハンドラを設定するのではなく、コンストラクタで行ったほうがよろしいかと
loop内ではIntervalとEnabledの設定だけにしたほうが良いと思います。

追記

C#

1 public Form1() 2 { 3 InitializeComponent(); 4 button1.Enabled = true; 5 button2.Enabled = false; 6 //イベントハンドラの設定 7 timer1.Tick += new EventHandler(Main_loop); 8 timer2.Tick += new EventHandler(sabu_loop); 9 } 10

でloop1内などでは、イベントハンドラを設定する必要はありません。

というか、使うタイマーがWindows.Forms.Timerなのであれば、フォームデザイナ上で配置してイベント登録すれば、このようなことにならないかと思います。

投稿2018/11/16 01:53

編集2018/11/16 03:33
YAmaGNZ

総合スコア10258

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

warks1

2018/11/16 02:52

回答ありがとうございます。 質問文のソースも変更しました。 Formが消えずに停止するようになったのですが、停止してから再開した際に2回動くようになってしまいました。何かおかしい点等分かれば教えていただけないでしょうか。
YAmaGNZ

2018/11/16 03:03

回答にイベントハンドラをloop内で設定しないように書いたのはこの為です。 イベントハンドラが設定されているところに timer1.Tick += new EventHandler(eventHandler); ともう一度設定した場合、上書きされるのではなく、追加されます。 なので、イベントが発生した時に登録されているイベントハンドラが順次呼ばれますので、イベントハンドラが複数回呼ばれることになります。
warks1

2018/11/16 03:21

無知で申し訳ありません。 質問文のソースを再度変更しました。 このような解釈で問題ないでしょうか。
warks1

2018/11/16 03:45

追記ありがとうございます。 質問文のソースを追記していただいたように変えたところ、ループが何度も瞬間で発生しました。。 ご丁寧に説明いただいているのになかなか理解が追いつかず申し訳ありません。 もう少し、回答いただいた内容で少しずつ理解していこうかと思います。
YAmaGNZ

2018/11/16 03:56

Intervalはボタンが押された時に設定してください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問