C#で一定時間ごとに処理させようと思ってます。
大まかな処理の流れは以下です。
処理の流れ
処理1→処理2→処理3→[1秒]→処理1→処理2→処理3→[1秒]→処理1→処理2→処理3→[3秒]→処理1→処理2→処理3→[1秒]→・・・
「処理1→処理2→処理3→[1秒]」が一つの処理の単位で、これが3回終われば3秒待つというような処理を書こうとしています。
上記を実現するのに、DispatcherTimerを二つ使って処理を書いたのですが、[3秒]にあたる待ち時間が、初めに実行している処理1からの経過時間となってしまい、処理3終了から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(); DispatcherTimer timer2 = new DispatcherTimer(); string[] files = { "a", "b", "c" }; int fileIter = 0; public MainWindow() { InitializeComponent(); timer.Interval = TimeSpan.FromMilliseconds(1000); timer.Tick += send; timer2.Interval = TimeSpan.FromMilliseconds(3000); timer2.Tick += exec; } private void send(object sender, EventArgs e) { Console.WriteLine("send関数で" + files[fileIter++] + "を実行中"); if (fileIter == files.Length) { timer.Stop(); fileIter = 0; } } private void exec(object sender, EventArgs e) { Console.WriteLine("send中"); textBox.Text = "実行中"; timer.Start(); } private void button_Click(object sender, RoutedEventArgs e) { timer2.Start(); } private void button1_Click(object sender, RoutedEventArgs e) { timer2.Stop(); timer.Stop(); } } }
[補足]
皆様、迅速なご回答ありがとうございます。適切な説明になっていない点もあり、改めて実現したい処理の流れを以下に記載させていただきます。
処理の流れ
func関数実行[1秒]→func関数実行→[1秒]→func関数実行→[3秒]→func関数実行→[1秒]→・・・
「func関数実行→[1秒]」が一つの処理の単位で、これがn回終われば3秒待つというような処理の流れです。
上記を実現するのに、以下ソースコードを書きました。ここで改めて質問させていただきたいのですが、timerのintervalプロパティを変更する、というのは適切なのでしょうか(intervalプロパティを変更し、待ち時間を変更させるというのは使い方が違う気がしてます)。
また、GUI上に配置するボタン押下で繰り返し実行処理を終了させたく、Zuishin様から頂いたTask.Delay()関数を使ったwhile文ループでは一度forループに入ると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); } } }
回答2件
あなたの回答
tips
プレビュー