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

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

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

Re[12]: System.Timers.Timerでのイベント処理


(過去ログ 22 を表示中)

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

■9602 / inTopicNo.1)  System.Timers.Timerでのイベント処理
  
□投稿者/ nbmyou (44回)-(2007/10/31(Wed) 15:40:03)

分類:[.NET 全般] 

当掲示板には、たびたびお世話になっております。
初心者のnbmyouと申します。

現在、VisualStudio2005のc#で、ポーリングによるフォルダ監視を行うWindowsサービスを作っています。

ポーリング間隔は、System.Timers.Timerクラスを使用し、一定の時間(たとえば5分)ごとにイベントを発生させ、
そのなかでフォルダ検索、目的のファイル抽出等を行っています。

そこで質問なのですが、
Timerの間隔を例えば10秒にした場合、10秒毎に発生するイベントの処理はどのように動作するものなのでしょうか。

わからないのは、以下のような内容です。
+++++++++++++++
サービス開始後、
最初のイベントで、あるファイル(A)を別フォルダにコピーする処理中に次のイベントが発生した場合、
次のイベントは、最初のイベントが終わってから動作を始めるものなのか、
それとも、別スレッドで動作を始め、同じファイルをコピーし始めるものなのか。
+++++++++++++++

上記の例ではどちらでも特に問題ないと思いますが、
コピー後に元ファイルを削除するようなつくりにしている場合は、
2番目のイベントでコピーしようとしたところでファイルが削除されてしまうなど、不都合があるような気がし、
質問させていただきました。

お手数ですが、ご教授いただけるとありがたいです。
よろしくお願いいたします。
引用返信 編集キー/
■9605 / inTopicNo.2)  Re[1]: System.Timers.Timerでのイベント処理
□投稿者/ Hongliang (205回)-(2007/10/31(Wed) 16:01:50)
Hongliang さんの Web サイト
MSDN の System.Timers.Timer クラスの解説に書かれていますが、その上での質問でしょうか?
引用返信 編集キー/
■9608 / inTopicNo.3)  Re[2]: System.Timers.Timerでのイベント処理
□投稿者/ nbmyou (45回)-(2007/10/31(Wed) 16:23:35)
No9605 (Hongliang さん) に返信
> MSDN の System.Timers.Timer クラスの解説に書かれていますが、その上での質問でしょうか?

回答ありがとうございます。

すみません。MSDNの該当部分をちゃんと読んでいませんでした。
おっしゃっているのは、以下の部分ですよね。
++++++++++++++++++++
Elapsed イベントは、ThreadPool スレッドで発生します。
Elapsed イベントの処理が Interval よりも長びくと、別の ThreadPool スレッドで同じイベントが再発生する場合があります。
このため、イベント ハンドラは再入可能であることが必要です。
++++++++++++++++++++

なるほど。別スレッドで動くので
「再入可能」な処理を書かなければならないということですね。


そこで、重ねて質問させてください。
++++++++++++++++++++
質問:「同じファイルについて処理しないようにするにはどのようにする方法が考えられますでしょうか」
++++++++++++++++++++

僕が思いつくものでは、
メンバ変数に「処理中のファイルパス」stringのListを持ち、
ファイル処理を開始する際に、この「処理中のファイルパス」をチェック。
処理中ではなければ、ここに処理するファイルパスを追加し、
処理する。(処理が終わったらListから削除する)

というものですが、これ以外に、いい方法はありますでしょうか?
すみませんが、よろしくお願いいたします。
引用返信 編集キー/
■9614 / inTopicNo.4)  Re[3]: System.Timers.Timerでのイベント処理
□投稿者/ nbmyou (46回)-(2007/10/31(Wed) 18:03:42)
2007/11/01(Thu) 13:46:33 編集(投稿者)

No9608 (nbmyou さん) に返信
> ■No9605 (Hongliang さん) に返信
>
> そこで、重ねて質問させてください。
> ++++++++++++++++++++
> 質問:「同じファイルについて処理しないようにするにはどのようにする方法が考えられますでしょうか」
> ++++++++++++++++++++

自己レスです。
マルチスレッドプログラミングについて勉強してから出直します。

回答ありがとうございました。
引用返信 編集キー/
■9633 / inTopicNo.5)  Re[4]: System.Timers.Timerでのイベント処理
□投稿者/ Tom Yama (15回)-(2007/11/01(Thu) 11:43:34)
# 解決済みのようですが、

No9614 (nbmyou さん) に返信
> マルチスレッドプログラミングについて勉強してから出直します。
System.Windows.Forms.Timerを使えば、「マルチスレッドプログラミングについて勉強」しなくてもよいのでは。

実際の用途からしても、正確なポーリング間隔は必要ないようですので、System.Windows.Forms.Timerで、十分だと思います。
解決済み
引用返信 編集キー/
■9641 / inTopicNo.6)  Re[5]: System.Timers.Timerでのイベント処理
□投稿者/ なちゃ (70回)-(2007/11/01(Thu) 15:07:48)
サービスでは止めた方がいいような気がしますが…
解決済み
引用返信 編集キー/
■9643 / inTopicNo.7)  Re[5]: System.Timers.Timerでのイベント処理
□投稿者/ nbmyou (47回)-(2007/11/01(Thu) 15:57:34)
No9633 (Tom Yama さん) に返信

> 実際の用途からしても、正確なポーリング間隔は必要ないようですので、System.Windows.Forms.Timerで、十分だと思います。

情報ありがとうございます。
このTimerクラスは、
「Windows OSのメッセージをベースとしているため、
タイマ・メッセージが発生したときにほかのメッセージの処理を行っているとタイマ・メソッドは呼び出されない。
また、その間に発生した複数のタイマ・メッセージは1つにまとめられる」
ということなのですね。

マルチスレッドで考えていましたが、再入が発生する場合は後の方のイベントを破棄しようと思っていたので、
紹介いただいた名前空間のTimerクラスを使用することで、簡単に実現できそうですね。
ありがとうございます。


No9641 (なちゃ さん) に返信

コメントありがとうございます。

> サービスでは止めた方がいいような気がしますが…

ものすごく根本的なところからの駄目だしですね(苦笑)
どういうことか、詳しく教えていただけませんか?
フォルダ監視は、Windowsサービスには向かないのでしょうか?
引用返信 編集キー/
■9648 / inTopicNo.8)  Re[6]: System.Timers.Timerでのイベント処理
□投稿者/ まどか (391回)-(2007/11/01(Thu) 16:35:34)
> 紹介いただいた名前空間のTimerクラスを使用することで、簡単に実現できそうですね。

Formインスタンス内でしか利用できないはずです。>単純クラスからは動作しない。MSDN参照。
しかもサービスだからGUIは無いですよね?

>>サービスでは止めた方がいいような気がしますが…
>
> ものすごく根本的なところからの駄目だしですね(苦笑)
> どういうことか、詳しく教えていただけませんか?
> フォルダ監視は、Windowsサービスには向かないのでしょうか?

いや、上記も含めてSystem.Windows.Forms.Timerのことだと思います。
引用返信 編集キー/
■9656 / inTopicNo.9)  Re[7]: System.Timers.Timerでのイベント処理
□投稿者/ mあ@反省中 (3回)-(2007/11/01(Thu) 17:40:36)
http://www.itmedia.co.jp/enterprise/articles/0502/01/news083.html

なんだか、自動生成されるコードも半端じゃなく難しそうだけど、相当知識要るのでは?

再入嫌なら、タイマーイベントが発生したら、止めればいいだけなのでは?


引用返信 編集キー/
■9663 / inTopicNo.10)  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を待つ。

という感じでしょうね。

引用返信 編集キー/
■9670 / inTopicNo.11)  Re[9]: System.Timers.Timerでのイベント処理
□投稿者/ mあ@反省中 (6回)-(2007/11/01(Thu) 22:43:19)
2007/11/01(Thu) 22:43:39 編集(投稿者)
No9663 (れい さん) に返信

http://www.atmarkit.co.jp/fdotnet/mthread/mthread03/mthread03_03.html

勉強になりましたm(__)m

でもスレ主さんは理解できたのかな?


boolean flag = false;

...

private elapsed_timer(Object o, ElapsedEventArgs e)
{
   if (!flag) {
      flag = true;
      console.writeline("start");
      //shori
      console.writeline("...end");
      flag = false;
   }
   else {
     console.writeline("sagyouchu");
   }
}

これだとflag = false するタイミングでカナリの頻度で
sagyouchu と ...end が逆になるからどーしたもんかな
と思っていたのでした。
SyncLock は真っ先に浮かんだのですけど、VB ですしね。
C# でロックってどーやんの?でしたから。
Mutexかセマフォなんて大げさ実装しか手が無いのかな、
と思いあぐねておりました。


引用返信 編集キー/
■9673 / inTopicNo.12)  Re[10]: System.Timers.Timerでのイベント処理
□投稿者/ れい (159回)-(2007/11/01(Thu) 23:32:30)
No9670 (mあ@反省中 さん) に返信
> でもスレ主さんは理解できたのかな?

あぅ
説明、下手でしたか。
私も反省しないといけないようです。

> これだとflag = false するタイミングでカナリの頻度で
> sagyouchu と ...end が逆になるからどーしたもんかな
> と思っていたのでした。

それはまた違う問題だと思います。
Consoleクラスはスレッドセーフですが、
出力の順番までは保証されてなくて、そこからくるのではないかと。

探した限りでは保証してるとも、保証してないとも書いていません。
他のプラットフォームでも、明示的にバッファのフラッシュとかしない限り
普通は順番までは保証してないので、
.Netでもたぶん、保証してないと思います。

保証するとかなりコストが高くつきますし。

> SyncLock は真っ先に浮かんだのですけど、VB ですしね。
> C# でロックってどーやんの?でしたから。
> Mutexかセマフォなんて大げさ実装しか手が無いのかな、
> と思いあぐねておりました。

Synclock(lock)は便利で分かりやすくて、すごく良いですよね。
C++時代は同じようなものをマクロで作っていたような気がします。

Interlockも同じくらい便利で分かりやすいです。しかも早くて軽いです。
ですが、同期オブジェクトではないので、「待ち」ができません。
Interlock+Sleepではパフォーマンス的に良くないので、
待ちがいる時には同期オブジェクトを使わなくてはいけないのですが、
MutexやEventは私には扱いづらいので、最近は避けるようになってしまいました。

適材適所にしなければいけませんよね。
引用返信 編集キー/
■9689 / inTopicNo.13)  Re[9]: System.Timers.Timerでのイベント処理
□投稿者/ nbmyou (48回)-(2007/11/02(Fri) 11:19:49)
2007/11/02(Fri) 11:44:48 編集(投稿者)

No9663 (れい さん) に返信
No9656 (mあ@反省中 さん) に返信

丁寧な回答どうもありがとうございます。
お二方への同時返信である旨、失礼かとは思いますがご容赦願います。


> でもスレ主さんは理解できたのかな?

すみません。正直、半分も理解できていないと思います。
そこで、数点質問させていただけますでしょうか。

質問の前に念のため、作成しようとしている監視の内容について概要をお伝えいたします。
●DBが動作しているサーバ上で動くサービス。
●監視は数分おきのポーリングで行う。
●監視フォルダにXMLファイルが存在する場合、以下の処理を行う。
 ・バックアップ用フォルダへのコピー
 ・XMLファイルの読み取り
 ・読み取ったデータのDB登録
 ・監視フォルダ内の処理済XMLファイルを削除
大雑把にこんな感じのものです。


次に質問の内容ですが、

@
上記に示したような内容の処理内容なので、重くてもスピード重視というよりは、
基本的に軽く動作するように実装したく思っております。それであれば、
> シングルスレッド同期ファイルアクセスが最高であろうと思われます。
> 速度が足りないときはファイルアクセスを非同期にして増やすのがいいでしょう。
ということで、変わりありませんでしょうか。

A
無知で申し訳ないのですが、「ワーカースレッド」とは、
「作業を行うスレッド」というような意味合いで間違いありませんでしょうか。
それとも、何か実装方法など、特別な方法をとったもののことなのでしょうか。
googleで検索をかけてみると、この言葉はたくさんひっかかってくるのですが、
「ワーカースレッド」そのものに対する説明を見つけられず、意味を正確に理解することができておりません。
お手数ですが、教えていただけると助かります。

A
System.Windows.Forms.Timerは使わないべきである点は理解できました。
そこで、れいさんが説明してくださった内容についてなのですが

> 監視をシングルスレッドでやるなら、
> ワーカースレッドで時刻を監視して、
> 定期的に処理するのが一番楽で軽いですね。
> Sleepは重くないですし、それほどいい加減でもないので。
>
> System.Timers.Timerを使いたいなら、
> シングルスレッド化しないといけません。
> ロックオブジェクトをいれてクリティカルセクションを構成したり、
> 専用のワーカースレッドを用意し、
> Timerイベントからワーカースレッドへ、
> イベントを通知するのが普通かと思います。

上記の内容は、
 ・System.Timers.Timerを使用する。
 ・Sleepを使用する。(Thread.Sleepをタイマー代わりに使用するということでしょうか?)
という2択を示してくださった、という認識で間違いありませんでしょうか。
また、「ロックオブジェクト」「クリティカルセクション」についても(言葉の意味から)理解できていないのですが
下のCで説明してくださっている内容に含まれている意味のものでしょうか。


C
> 再入フラグ用integer or booleanを一個用意。
> Timerイベント先頭でInterlockedクラスを用いてinteger型をチェック。
> 再入してるなら何もせずに帰る。
> 再入してないなら監視タスクを実行。
> 監視タスクが終わったら再入フラグをクリア。
>
> もしくは。
>
> AutoResetEventを用意。
> TimerイベントではEventをセットするだけ。
> ワーカースレッドはEventを待つ。
> イベントが通知されたら監視タスクを実行。
> 監視タスクが終わったらまたAutoResetEventを待つ。

上記のどちらかの方法をお勧めしてくださっているのですよね?
AutoResetEventクラスという、「イベントが発生したことを待機中のスレッドに通知」するクラスがあるということを、
今回始めて知りました。情報ありがとうございます。
これら上記どちらの方法を使用しても、同じ処理(タイマイベントで処理実行時、次のタイマイベントが発生しても、後のイベントは何もしない)を
行うことができるという認識で間違いありませんでしょうか。


4点も申し訳ありません。。。
さしあたって質問させていただきましたが、
回答を待つ間、自分でも再度いろいろ調べたり、テスト実装してみて勉強してみようと思います。

お手数ですが、回答いただけるととても助かります。
よろしくお願いいたします。
引用返信 編集キー/
■9690 / inTopicNo.14)  Re[10]: System.Timers.Timerでのイベント処理
□投稿者/ Tom Yama (17回)-(2007/11/02(Fri) 12:07:14)
No9689 (nbmyou さん) に返信
タスクスケジューラを使うという手は、ないのでしょうか?
引用返信 編集キー/
■9691 / inTopicNo.15)  Re[11]: System.Timers.Timerでのイベント処理
□投稿者/ なちゃ (71回)-(2007/11/02(Fri) 12:34:24)
ありだと思いますけど調整はさらに面倒が増えると思いますよ。

引用返信 編集キー/
■9692 / inTopicNo.16)  Re[12]: System.Timers.Timerでのイ
□投稿者/ PATIO (34回)-(2007/11/02(Fri) 13:33:43)
2007/11/02(Fri) 13:38:03 編集(投稿者)
2007/11/02(Fri) 13:35:51 編集(投稿者)

気になったんですが、問題のXMLファイルはファイル名固定で1ファイルしかできないのでしょうか?

ファイル名がユニークになるように振られて複数ファイル共存可能であるとして
ファイルが作成されて処理するまでの時間にシビアな物が無いなら
単純に処理中だったら何もせずに素通りして次のイベントで処理でも良いのではと
感じました。実際のXMLファイルの処理に掛かる時間にどれくらいを見込んでいて
インターバルタイムをどの程度で考えているのかで複雑さも変わりそうです。
処理スピードがファイルを置くスピードよりも十分に速い事が保障できるのであれば、
仕組みを簡略化する事も可能でしょうし。

ファイルを置くタイミングと処理をするタイミングに関してシビアではなく、
置かれた順番に処理できれば良いと言う話ならポーリングでやるよりも
シングルスレッドでSleepを使ってタイミングを取るようにすれば、
別に二つ同時に動く心配も要りませんからね。
その辺の仕様次第で仕組みの複雑さもどんどん変わってくると思います。

引用返信 編集キー/
■9695 / inTopicNo.17)  Re[11]: System.Timers.Timerでのイベント処理
□投稿者/ nbmyou (49回)-(2007/11/02(Fri) 14:06:07)
2007/11/02(Fri) 14:08:35 編集(投稿者)

No9690 (Tom Yama さん) に返信

回答ありがとうございます。

> タスクスケジューラを使うという手は、ないのでしょうか?

なるほど。今回はWindowsサービスで作成するという仕様なのですが、
タスクスケジューラというものを使用するという方法もあったのですね。
情報ありがとうございます。


No9691 (なちゃ さん) に返信

回答ありがとうございます。

> ありだと思いますけど調整はさらに面倒が増えると思いますよ。

そういうものなのですか?
タスクスケジューラというものの存在自体今回初めて知ったのですが、
いろいろ情報をいただけると、今後のためにもとても勉強になります。
どうもありがとうございます。


No9692 (PATIO さん) に返信

回答ありがとうございます。

> 気になったんですが、問題のXMLファイルはファイル名固定で1ファイルしかできないのでしょうか?

すみません。そういう情報が抜けていました。
+++++++++++++
XMLファイルはファイル名固定ではなく、複数のファイルが監視フォルダに置かれることを想定しています。
別に作成してあるプログラムからXMLファイルを出力するので、
基本的にはユニークな名前となるはずですが、監視フォルダ自体は特にアクセス制限をかけるわけではないので、
手動で同名ファイルが置かれることも考えられます。

また、XMLファイルが作成途中(例えば大容量のファイルで、監視フォルダへのコピーに時間がかかっている状態)ではないことの判断は、
拡張子がaaa(仮)の同名ファイルが同じフォルダに存在するかどうかで判断します。
+++++++++++++

> ファイル名がユニークになるように振られて複数ファイル共存可能であるとして
> ファイルが作成されて処理するまでの時間にシビアな物が無いなら
> 単純に処理中だったら何もせずに素通りして次のイベントで処理でも良いのではと
> 感じました。実際のXMLファイルの処理に掛かる時間にどれくらいを見込んでいて
> インターバルタイムをどの程度で考えているのかで複雑さも変わりそうです。

はい、イベント処理中に次のタイマイベントが発生した場合、後のイベントは何も処理しないように作成しようと思っています。
ただ、ポーリング間隔・監視フォルダ・バックアップフォルダは、
XMLかini形式の「設定ファイル」で自由に設定できる(デフォルトは5分程度)ように考えているので、
この設定によって間隔が短くされる可能性がある状態です。

> 処理スピードがファイルを置くスピードよりも十分に速い事が保障できるのであれば、
> 仕組みを簡略化する事も可能でしょうし。

特に保障できるかは定かではありませんが、
簡略化するとは、たとえばどのような方法がありますでしょうか。

> シングルスレッドでSleepを使ってタイミングを取るようにすれば、
> 別に二つ同時に動く心配も要りませんからね。
シングルスレッドでSleepを使うということは、
例えばポーリング間隔が5分と設定された場合、XMLファイルの処理が終わってから5分後に動作するような仕組みということでしょうか。
(処理に2分かかったとすると、実際には次の処理は7分後となる?)
できれば、5分と設定したら、5分ごとに処理が行われるようにしたいので、
それであればSleepを使う方法は、今回は避けようかと思っています。
引用返信 編集キー/
■9697 / inTopicNo.18)  Re[12]: System.Timers.Timerでのイベント処理
□投稿者/ 魔界の仮面弁士 (513回)-(2007/11/02(Fri) 15:07:35)
No9695 (nbmyou さん) に返信
> 拡張子がaaa(仮)の同名ファイルが同じフォルダに存在するかどうかで判断します。
「*.aaa の名でコピーして、コピー完了後、それを *.xml にリネーム」という手法も見かけます。

> 例えばポーリング間隔が5分と設定された場合、XMLファイルの処理が終わってから5分後に動作するような仕組みということでしょうか。
>(処理に2分かかったとすると、実際には次の処理は7分後となる?)
その場合、Sleep 時間を 5 分に設定すれば 7分後になってしまいますが、もっと短い Sleep 時間、
たとえば 15 秒に設定し、そのたびに「5分経過したかどうか」を判定して実行させるようにすれば、
次の実行は(7分後ではなく)5分後〜5分15秒程度の誤差に抑えられるかと。


あとは、ポーリング時間 5 分の間に処理が終わらなかった(たとえば 7 分かかる)場合に、
次の要求が来てしまった場合に、どのような対応を取るべきかも考えておく必要があるかも。
 (案1)他の要求も、最大 n 件まで並行で稼働させる。
 (案2)処理中の要求を中止させ、ただちに次の要求を開始する。
 (案3)処理中の要求を中止させ、次の5分後(つまり10分後)にそれを処理させる。
 (案4)処理中の要求が完了後、ただちに次の要求を開始する。
 (案5)処理中の要求が完了後、次の5分後(つまり10分後)にそれを処理させる。
引用返信 編集キー/
■9698 / inTopicNo.19)  Re[12]: System.Timers.Timerでのイ
□投稿者/ PATIO (35回)-(2007/11/02(Fri) 15:12:46)
2007/11/02(Fri) 15:18:42 編集(投稿者)
2007/11/02(Fri) 15:13:47 編集(投稿者)

No9695 (nbmyou さん) に返信
> XMLファイルはファイル名固定ではなく、複数のファイルが監視フォルダに置かれることを想定しています。
> 別に作成してあるプログラムからXMLファイルを出力するので、
> 基本的にはユニークな名前となるはずですが、監視フォルダ自体は特にアクセス制限をかけるわけではないので、
> 手動で同名ファイルが置かれることも考えられます。
>
> また、XMLファイルが作成途中(例えば大容量のファイルで、監視フォルダへのコピーに時間がかかっている状態)ではないことの判断は、
> 拡張子がaaa(仮)の同名ファイルが同じフォルダに存在するかどうかで判断します。
> +++++++++++++

この辺の融通がきくようにすればするほどシステム的なチェックとか誤動作しない為の仕組みとかが
増えていってどんどん複雑になると言う話です。
ある程度、運用側に制限をかける事が可能ならそっちに振ってシステムを簡単にした方がメンテは
やりやすくなると言う話ですのでケース・バイ・ケースかと思います。


> はい、イベント処理中に次のタイマイベントが発生した場合、後のイベントは何も処理しないように作成しようと思っています。
> ただ、ポーリング間隔・監視フォルダ・バックアップフォルダは、
> XMLかini形式の「設定ファイル」で自由に設定できる(デフォルトは5分程度)ように考えているので、
> この設定によって間隔が短くされる可能性がある状態です。
>
>>処理スピードがファイルを置くスピードよりも十分に速い事が保障できるのであれば、
>>仕組みを簡略化する事も可能でしょうし。
>
> 特に保障できるかは定かではありませんが、
> 簡略化するとは、たとえばどのような方法がありますでしょうか。

処理スピードがファイルを置くスピードよりも十分に速い事が保障できるのであれば、
処理がまにあわなくてファイルがどんどん溜まると言うケースを想定する必要が無いので
シングルスレッドで一定間隔で処理と言う方法でも何とかなるかなと言う話です。
処理スピードが間に合わないとなると何か対策を考えないと最悪の場合(ディスクフル)を想定する必要が出てきます。


>>シングルスレッドでSleepを使ってタイミングを取るようにすれば、
>>別に二つ同時に動く心配も要りませんからね。
> シングルスレッドでSleepを使うということは、
> 例えばポーリング間隔が5分と設定された場合、XMLファイルの処理が終わってから5分後に動作するような仕組みということでしょうか。
> (処理に2分かかったとすると、実際には次の処理は7分後となる?)
> できれば、5分と設定したら、5分ごとに処理が行われるようにしたいので、
> それであればSleepを使う方法は、今回は避けようかと思っています。

そこは考え方一つだと思いますよ。
ミリ秒オーダーの正確性を求めないなら処理時間を計っておいてインターバル時間から
差し引けば良いだけの話なのでそんなに難しい話では無いと思います。
もし、処理時間がインターバル時間を上回った時はどうするのが妥当かは考える必要が
あるでしょうけれど。
選択肢は色々あるでしょう。すぐに次の処理を始めるのもよし、
上回った時は最低これだけ待つと言うルールを決めてその時間だけインターバルを取るのもよし。
処理中の時は処理しないと言う判断なら、処理時間とインターバルタイムの差分を
インターバルタイムから差し引いてその時間だけSleepでも良いかと思いますし。

引用返信 編集キー/
■9705 / inTopicNo.20)  Re[13]: System.Timers.Timerでのイ
 
□投稿者/ nbmyou (51回)-(2007/11/02(Fri) 16:04:20)
No9697 (魔界の仮面弁士 さん) に返信
No9698 (PATIO さん) に返信

回答ありがとうございます。

System.Timers.Timerを使うメリット(マルチスレッド処理ができる。時間が正確である)を必要とせず、
また今後マルチスレッドが必要になる仕様変更等が考えにくいのであれば、
シングルスレッド処理(Sleepを使用)で実装するほうが安全であり、パフォーマンスも問題はない、
ということですよね。

色々勉強になります。
魔界の仮面弁士さんに案として示していただいたような選択肢を頭にいれながら、
もう一度仕様について見直して、それに適した方法を探してみようと思います。
引用返信 編集キー/

次の20件>
トピック内ページ移動 / << 0 | 1 >>

管理者用

- Child Tree -