■9663 / ) |
Re[8]: System.Timers.Timerでのイベント処理 |
□投稿者/ れい (158回)-(2007/11/01(Thu) 19:10:22)
|
■No9656 (mあ@反省中 さん) に返信 > 再入嫌なら、タイマーイベントが発生したら、止めればいいだけなのでは?
これはダメな発想ですね。 タイマーイベントが発生してから止めるまでの間に、 もう一度イベントが発生する可能性がありますから。
サービスなので、 System.Windows.Forms.Timerを使うのもよしたほうがよいでしょうね。 できないことはないですが、 system.windows.forms.dllはでかいので、 無駄にメモリを喰うこともないでしょう。
スレッドモデルとIOモデルで分類すると、一般に4つの選択肢があります。
1 シングルスレッドで同期IO 2 シングルスレッドで非同期IO 3 マルチスレッドで各スレッドが同期IO 4 マルチスレッドで各スレッドが非同期IO
最初のは普通ですね。 ファイルアクセスは一般に遅いので、その間はスレッドが止まります。 スループットは小さいですが、無駄な処理は一切ありません。 そういう意味では最も効率的です。
2番目が理論上は最も高速にできます。 PCをこのプロセスが占有してよいなら、最速です。 管理する状態が増えてくるとプログラミングが大変になってきます。
3番目は仕事を分けられるときの手法です。 スレッド切り替えのコストがありますから、2よりは重くなります。 同期機構をちゃんといれないとダメです。
最後のはHTTPサーバーなどで使われる手で最も大変です。 マルチコア・マルチスレッドなPCではかなり早いですし、 大規模なものではこれを使わないと開発が激しく大変になります。
よく無駄にスレッド数を増やしてしまう人がいますが、 最近のまともなOSは非同期IOがありますから、 本来スレッドなど無くてもIO待ちのないプログラムが作れます。 スレッドを使ったほうが開発が楽な場合のみ、使うべきです。
具体的にどんな監視なのか分かりませんが、 クライアントPCでフォルダ監視をするサービスなら、 ユーザーが重く感じないように動いていて欲しいのではないでしょうか。 であるなら、PCへの負荷が小さく、トータルで最も効率のよい シングルスレッド同期ファイルアクセスが最高であろうと思われます。 速度が足りないときはファイルアクセスを非同期にして増やすのがいいでしょう。
監視をシングルスレッドでやるなら、 ワーカースレッドで時刻を監視して、 定期的に処理するのが一番楽で軽いですね。 Sleepは重くないですし、それほどいい加減でもないので。
System.Timers.Timerを使いたいなら、 シングルスレッド化しないといけません。 ロックオブジェクトをいれてクリティカルセクションを構成したり、 専用のワーカースレッドを用意し、 Timerイベントからワーカースレッドへ、 イベントを通知するのが普通かと思います。
再入フラグ用integer or booleanを一個用意。 Timerイベント先頭でInterlockedクラスを用いてinteger型をチェック。 再入してるなら何もせずに帰る。 再入してないなら監視タスクを実行。 監視タスクが終わったら再入フラグをクリア。
もしくは。
AutoResetEventを用意。 TimerイベントではEventをセットするだけ。 ワーカースレッドはEventを待つ。 イベントが通知されたら監視タスクを実行。 監視タスクが終わったらまたAutoResetEventを待つ。
という感じでしょうね。
|
|