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

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

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

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

ループ

ループとは、プログラミングにおいて、条件に合致している間、複数回繰り返し実行される箇所や、その制御構造を指します

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

Q&A

解決済

1回答

5950閲覧

C# timerクラスのIntervalプロパティの変更について

senkei_river

総合スコア15

C#

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

ループ

ループとは、プログラミングにおいて、条件に合致している間、複数回繰り返し実行される箇所や、その制御構造を指します

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

0グッド

0クリップ

投稿2020/05/13 15:08

C#で一定時間ごとに関数を実行するプログラムを作成してます。
大まかな処理の流れは以下です。

処理の流れ

func関数実行[1秒]→func関数実行→[1秒]→func関数実行→[3秒]→func関数実行→[1秒]→・・・

「func関数実行→[1秒]」が一つの処理の単位で、これがn回終われば3秒待つというような処理の流れです。

上記を実現するのに、以下ソースコードを書きました。

using System; using System.Windows; using System.Windows.Threading; namespace timerSamplePrj { /// <summary> /// MainWindow.xaml の相互作用ロジック /// </summary> public partial class MainWindow : Window { DispatcherTimer timer= new DispatcherTimer(); string[] files = { "a", "b", "c" }; int fileIter = 0; public MainWindow() { InitializeComponent(); timer.Interval = TimeSpan.FromMilliseconds(0); timer.Tick += func; } private void func(object sender, EventArgs e) { Console.WriteLine("func関数で" + files[fileIter++] + "を実行中"); if (fileIter == files.Length) { fileIter = 0; timer.Interval = TimeSpan.FromMilliseconds(3000); } else { timer.Interval = TimeSpan.FromMilliseconds(1000); } } private void button_Click(object sender, RoutedEventArgs e) { Console.WriteLine("exec開始"); timer.Start(); } private void button1_Click(object sender, RoutedEventArgs e) { Console.WriteLine("exec終了"); fileIter = 0; timer.Stop(); timer.Interval = TimeSpan.FromMilliseconds(0); } } }

質問事項

 上記ソースコードのように、timerのIntervalプロパティを変更する、というのは適切なのでしょうか(Intervalプロパティをプログラム実行中に変更し、待ち時間を変更させるというのは使い方が違う気がしてます)。
また、GUI上に配置するボタン押下で繰り返し実行処理を終了させたく、下記のようにwhile文ループで一度forループに入ると3回分の処理が実行されないよう、途中で処理を終了させるようにもしたいです。

while (終了ボタン押下されてない### ヘディングのテキスト) { for (int i = 0; i < 3; i++) { func(); await Task.Delay(1000); } await Task.Delay(3000); }

※過去に類似の質問もさせていただいたのですが、その派生で気になることがあり、再度質問させていただきます。

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

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

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

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

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

Zuishin

2020/05/13 15:48

派生でもなんでもない、同じ質問ですね。二番目のコードなど、私が提案したものそのままですが、それについていまだ何の言及もありません。
Zuishin

2020/05/13 15:56

逆にその時の質問でのベストアンサーは影も形もありません。なんなんですかこれ? 四の五の言わず自分の要求する仕様そのままの動くコード書いて捧げろと?
gentaro

2020/05/13 16:58 編集

> (Intervalプロパティをプログラム実行中に変更し、待ち時間を変更させるというのは使い方が違う気がしてます)。 そう思った理由は何でしょうか。 また、上記のコードは要求を満たしてないということなんでしょうか。 質問の趣旨がわからないため、まずそのあたりをハッキリさせてください。 > while (終了ボタン押下されてない### ヘディングのテキスト) { 「### ヘディングのテキスト」ってなんだろう。
senkei_river

2020/05/14 11:07

timerイベントは一定の周期で実行されるべきで、その周期がコロコロ変わるのは不適切な使い方をしてるのでないかなと思ったからです。 また、### ヘディングのテキストは誤記です。確認不足で申し訳ございませんでした。
退会済みユーザー

退会済みユーザー

2020/05/14 11:23 編集

別にタイマー動作中にIntervalを変更してはならないという記述はないので変更しても問題はありませんが、動作中に変更するのが気になるのであれば、System.Timers.TimerだとAutoReset(Falseだとイベントを一回だけ発生させる)というプロパティがあるので、そちらを使うという手もあります。
Zuishin

2020/05/14 11:22

コロコロ変えたいのにコロコロ変わるのが不適切とかもう何を言ってるのか。
senkei_river

2020/05/14 11:34

radian様、ご回答ありがとうございます。今回は一回だけ発生させるというのは想定してなかったですが、他のプロパティももう少し見てみます。
Zuishin

2020/05/14 11:38

まず今まで見てないこと自体が異常です。
gentaro

2020/05/14 11:40

> timerイベントは一定の周期で実行されるべきで、その周期がコロコロ変わるのは不適切な使い方をしてるのでないかなと思ったからです。 ライブラリの製作者目線だと、動作中に変更されて困るようなプロパティであればリードオンリーにして、コンストラクタかスタートさせるときのメソッドの引数でインターバルを受け取る設計しにます。 フレームワークに含まれるようなクラスがその程度の事を考慮していないとは思えません。
senkei_river

2020/05/14 11:51

gentaro様、ご回答ありがとうございます。確かに変更可能な設計になってますね。 皆様のご回答のおかげで少し理解が進みました。
Zuishin

2020/05/14 11:53

オウム返しをしてるだけで、理解が進んだようには見えませんねえ。
Zuishin

2020/05/14 11:55

まったく同じ質問を以前にしていますが、その時のベストアンサーが全く取り入れられていないので。
Zuishin

2020/05/14 11:57

口先だけ「わかったわかった」と言いながらその実コピペできるコードだけを望むようなことでは何も作れないでしょう。
guest

回答1

0

ベストアンサー

タイマのインターバルを1秒にする。
カウンタを持って、Tickイベントハンドラ(ここではfunc)の中でカウンタを更新する。
カウンタに応じてTickイベントハンドラ内の処理を分岐させる。
という風にしてはどうでしょうか。

投稿2020/05/13 15:40

darudaru

総合スコア36

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

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

senkei_river

2020/05/14 11:08

ご回答ありがとうございます。周期を変動させなくてもTickイベントハンドラでカウンタを持たせてやればいいですね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問