C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[4]: Threading.Timerの呼び出し間隔が異常


(過去ログ 111 を表示中)

[トピック内 5 記事 (1 - 5 表示)]  << 0 >>

■65939 / inTopicNo.1)  Threading.Timerの呼び出し間隔が異常
  
□投稿者/ もんた (5回)-(2013/03/25(Mon) 18:23:27)

分類:[C#] 

こんにちは、もんたです。
System.Threading.Timerについて質問させて頂きたいと思います。

複数のスレッド(Invokeで呼び出し)でTimerを作成し定期的な処理を実行させているのですが、
ごくまれにコールバックが物凄い勢い(0秒間隔?)で呼び出されてしまいます。
処理内容は、

@各スレッドのコンストラクタでTimerをnewし、とりあえずTimer.Change(Timeout.Infinite, Timeout.Infinite)に設定。
Aボタン契機で実行されるメソッドでTimer.Change(0, 1000)に設定し実行(全スレッドで行われる)
Aコールバック内の初めにTimerをTimer.Change(Timeout.Infinite, Timeout.Infinite)で停止し、コールバックの最後にTimer.Change(0, 1000)で実行
 (間にTimerに関係のない処理は有り)

といった形で、ABは10時間ほど実行され続けます。
呼び出し間隔の設定はTimer.Change(0, 1000)とTimer.Change(Timeout.Infinite, Timeout.Infinite)のみ使用しています。
おそらくTimerが破壊されてしまっていると思うのですが、こういった現象はどういった場合に起こるのでしょうか?

一時しのぎの対応方法でも構いませんで、ご教授頂けると幸いです。

【環境】
Windows7
.Net4.5
VS2012
C#
WPF
引用返信 編集キー/
■65940 / inTopicNo.2)  Re[1]: Threading.Timerの呼び出し間隔が異常
□投稿者/ とっちゃん (63回)-(2013/03/25(Mon) 19:22:22)
とっちゃん さんの Web サイト
No65939 (もんた さん) に返信

タイマーを設定後、1回だけ呼び出されればいいのであれば、
Timer.Change( 0, Timeout.Infinite )
でいいのではありませんか?

この設定で、呼び出されると
タイマー処理に結びつけたデリゲートが呼ばれるタイミングで
Timer.Change( Timeout.Infinite, Timeout.Infinite );
が内部的に呼び出されています。

デリゲートで呼ばれた処理後に、ふたたびタイマーを発行させたいのなら
その終了時などに、Timer.Change(0, Timout.Infinite ) とすれば
またすぐにデリゲートが呼ばれます。

もし、これでもガンガン呼び出されてしまうとしたら、
デリゲートの中で処理をスキップしてしまっていて、即座に次ぎに行ってしまう
という可能性が高い気がします(気がするだけで本当かどうかはわかりません)。

もしかしたら、0指定が怪しいということもあるので、
1とか、0ではない正数を与えてみてはいかがでしょう?

引用返信 編集キー/
■65941 / inTopicNo.3)  Re[2]: Threading.Timerの呼び出し間隔が異常
□投稿者/ pang2 (14回)-(2013/03/25(Mon) 19:48:10)
2013/03/25(Mon) 19:50:37 編集(投稿者)

> コールバックの最後にTimer.Change(0, 1000)で実行

これだと直ちに次のコールバックが実行されます。

Timer.Change(1000, 0) でしょう。

Timer.Change メソッド (Int32, Int32)
http://msdn.microsoft.com/ja-jp/library/yz1c7148(v=vs.80).aspx
の解説参照
引用返信 編集キー/
■65951 / inTopicNo.4)  Re[3]: Threading.Timerの呼び出し間隔が異常
□投稿者/ もんた (6回)-(2013/03/26(Tue) 16:41:56)
>とっちゃんさま、pang2さま

回答ありがとうございます。
Timerを少し単純に考えすぎていたようですね。
Timeout.Infiniteは精々タイマーの停止くらいに考えていました。
「1回目のコールバックぐらいすぐに動いても大丈夫だろう」と思い(0, 1000)にしていたのですが、
それも良くなかったようですね。

お二人に教えて頂いた方法で暫く動作させてみようと思います。
確認でき次第解決済みにしたいと思います。

ありがとうございました!
引用返信 編集キー/
■65952 / inTopicNo.5)  Re[4]: Threading.Timerの呼び出し間隔が異常
□投稿者/ とっちゃん (64回)-(2013/03/26(Tue) 18:23:20)
とっちゃん さんの Web サイト
No65951 (もんた さん) に返信
> 「1回目のコールバックぐらいすぐに動いても大丈夫だろう」と思い(0, 1000)にしていたのですが、

もしかして、定期的に呼ばれることが必要なのではなく、トリガー(ボタンを押す)をタイミングとして
サブスレッドで連続処理がさせたいだけでしょうか?

もしそうなら、System.Threading.Tasks.Task、System.Threading.Tasks.Parallel あるいは
System.Threading.Tasks.Dataflow などの利用を検討してもいいかもしれません。
具体的にどんなことをしているのかわからないので必ずしも新しいタスク処理がいいとは言えませんけど。

単純に、別スレッドでループを回せばよくて、そのスタートだけそろえたい。。。ということなら
ManualResetEvent を利用する方法もあります。

タイマー以外の待機方法も検討してみてください。


引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -