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

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

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

Re[7]: フォルダ監視Windowsサービスのエラー処理


(過去ログ 22 を表示中)

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

■9703 / inTopicNo.1)  フォルダ監視Windowsサービスのエラー処理
  
□投稿者/ nbmyou (50回)-(2007/11/02(Fri) 15:51:15)

分類:[.NET 全般] 

2007/11/02(Fri) 17:03:26 編集(投稿者)
2007/11/02(Fri) 16:34:55 編集(投稿者)
2007/11/02(Fri) 15:57:39 編集(投稿者)

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

現在、VisualStudio2005のC#で、下記のようなフォルダ監視のWindowsサービスを作成しています。
+++++++++++++++++
@DBが動作しているサーバ上で動くサービス。
A監視は数分おきのポーリングで行う。
B監視フォルダにXMLファイルが存在する場合、以下の処理を行う。
 (XMLファイルは、複数存在することを認めています)
 ・バックアップ用フォルダへのコピー
 ・XMLファイルの読み取り
 ・読み取ったデータのDB登録
 ・監視フォルダ内の処理済XMLファイルを削除
 (XMLファイルの書式要因のNGがあった場合は、そのXMLファイルをエラーXMLフォルダへ移動)
Cエラー発生時・ログを残したい時は、アプリケーションログに出力
+++++++++++++++++
大雑把にこんな感じのものです。

そこで質問なのですが。

上記Bの各処理は上から順に行っていきますが、
ファイル操作・DB操作で例外が発生することが考えられます。
(例えば、読み込もうとしたときには該当ファイルが既になかった・・・等)

現在、僕が考えている仕様では、
「例外が発生した場合、どの処理も10回までリトライし、
それでもNGであれば、そこでそのファイルの処理はあきらめ、次のファイル処理へ移る」
というようにしています。
本当はファイル毎の処理はひとつの流れなので、トランザクションをかけるように
途中で失敗したら元に戻すようにも考えかけたのですが、
その処理でも例外が発生する可能性があるので、どこまでどうすればいいのかわからなくなってきてやめました。

上記の仕様で、問題はありますでしょうか。
また、リトライやエラー処理は、みなさんであればどのように行いますでしょうか。


どこまでシビアに処理しなければならないかによって、ケースバイケースではあると思いますが、
参考までにお聞かせいただければ幸いです。

御手数ですが、よろしくお願いいたします。
引用返信 編集キー/
■9713 / inTopicNo.2)  Re[1]: フォルダ監視Windowsサービスのエラー処理
□投稿者/ れい (162回)-(2007/11/02(Fri) 16:50:40)
No9703 (nbmyou さん) に返信
> 上記の仕様で、問題はありますでしょうか。
> また、リトライやエラー処理は、みなさんであればどのように行いますでしょうか。

もう一つのスレッドのほうに書いてしまいましたが、
安全・安定を心がけるべきです。
安定というのは、多少エラーがあっても問題ない方向に流れていくようなアルゴリズムにする、
ということです。
力技で例外処理をしてると、肥大化していく一方です。きりがありません。

例えば。
定期的に監視するなら、10回もリトライは要りません。
ポーリングの度に全てのファイルを1回試す、としておけばいいと思いますよ。
ファイルが書き込み中なら飛ばされて次の機会に登録されるわけですし、
壊れたファイルはいつまでも登録されないのですから、問題ありません。
リトライのコードを書くとそこでもまたバグが発生する可能性があります。

ファイルのコピー・削除を行うなら、「移動」にすべきです。
これならアトミック性が保証されています。

ファイル操作も、読み込みのためにはパフォーマンスがいいですから「共有ロック」を行うのが普通ですが、
読み込みでも敢えて「排他ロック」を使うと、他のプロセス、スレッドからファイルが使われるのを防げます。

DB登録も、誤って2重に登録しないようにしておくべきです。
これも簡単ですよね。

間違った発想で例外処理を始めてしまうとすごく大変です。
慣れるまで大変ですが、

・例外処理が絡んでたりネストしてるのはダメな可能性が多い。
・単純な処理のはずなのにコードが多いのはダメな可能性が多い。
・マルチスレッドのはずなのにコードが少なすぎるのもダメな場合が多い。
・テンポラリファイルとかは要らない場合が多い

こんなのを私は意識してる気がします。
この辺がうまくできる人がいいプログラマだと思ってます。
がんばってください。
引用返信 編集キー/
■9742 / inTopicNo.3)  Re[2]: フォルダ監視Windowsサービスのエラー処理
□投稿者/ ちゃっぴ (71回)-(2007/11/03(Sat) 14:31:34)
ちゃっぴ さんの Web サイト
2007/11/03(Sat) 14:38:06 編集(投稿者)
2007/11/03(Sat) 14:38:02 編集(投稿者)

Vista 移行なら KTM が使えそうですが。

まあ、この程度ならそんなものも必要ないでしょうから。

1. 対象の folder を探索

2. 排他 lock かけて file 読み込み
→ 読み込めなかったら終了

3. DB 登録 (commit しない)
→ 登録できなかったら終了

4. Backup folder へ file 移動
→ 失敗したら終了

5. DB を commit
→ 失敗したら log 吐いて終了
この場合の recovery は手動で実行

数分おきの polling ならこれを task scheduler から実行でいいと思いますよ。

ついでに欲を言えば、file の作成を trigger に処理を行うという仕様自体できる限り避けるべきだと思います。
引用返信 編集キー/
■9743 / inTopicNo.4)  Re[3]: フォルダ監視Windowsサービスのエラー処理
□投稿者/ ちゃっぴ (72回)-(2007/11/03(Sat) 14:45:19)
ちゃっぴ さんの Web サイト
あ、あと file の移動ですが、移動後の filename に処理時の日付(この場合分単位で十分かと)を入れておくようにして、上書きを防ぐべきですね。
引用返信 編集キー/
■9753 / inTopicNo.5)  Re[4]: フォルダ監視Windowsサービスのエラー処理
□投稿者/ れい (165回)-(2007/11/03(Sat) 22:48:20)
No9743 (ちゃっぴ さん) に返信
> あ、あと file の移動ですが、移動後の filename に処理時の日付(この場合分単位で十分かと)を入れておくようにして、上書きを防ぐべきですね。

これは私は反対です。
上書きを防ぐなら、移動先が存在する場合失敗するようなメソッドを使うべきです。

ファイル名に依存する仕組みはよくないと思います。
引用返信 編集キー/
■9822 / inTopicNo.6)  Re[5]: フォルダ監視Windowsサービスのエラー処理
□投稿者/ nbmyou (53回)-(2007/11/05(Mon) 17:13:38)
2007/11/05(Mon) 17:15:12 編集(投稿者)

No9753 (れい さん) に返信
No9743 (ちゃっぴ さん) に返信

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

コピーではなく移動、リトライ不要など、参考になる意見がたくさんあり、
とても助かります。

ファイル名にタイムスタンプを追加する方法や、それは「ファイル名に依存する方法」という意見など、
どちらも納得のいくもので、なかなか難しいなぁと思いました。

参考にさせていただきながら、安全・安定を心がけ、
あまり例外処理を増やさないように考えてやってみます。


+++++
エラー処理で続けて質問させてください。


DB処理でエラーになり、それがXMLの項目値の問題であった場合について。

XMLファイルの項目10個に問題があった場合、
アプリケーションログに10個エラーログを吐くのは、結構鬱陶しい気がするのですが、
せっかくおかしな点をプログラムで判断できているのであれば、
ログとして出力して、ユーザに知らせた方が親切である気がします。

このような場合、
・ログを、アプリケーションログではなく、テキストに出力する
という以外に、どのような方法を考えつきますでしょうか。

お手数ですが、回答お待ちしております。
よろしくお願いいたします。
引用返信 編集キー/
■9842 / inTopicNo.7)  Re[6]: フォルダ監視Windowsサービスのエラー処理
□投稿者/ mあ@反省中 (10回)-(2007/11/05(Mon) 22:34:02)
No9822 (nbmyou さん) に返信

> このような場合、
> ・ログを、アプリケーションログではなく、テキストに出力する
> という以外に、どのような方法を考えつきますでしょうか。

イベントログ。
指定メールアドレスへのメール送信、Windowsサービスでこれをやっていいかどうかはわからんが、
最近のMS社のツールでも落ちた時はメール送信してもいいか?って聞いてくるのでたぶんOKでしょう。


というか、そろそろ、
OnStart()
OnStop()
run()
各メソッドの内容を見せてくれてもいいのでは?

これまで色々アドバイスがあったが、どれくらい理解できているのかが知りたいところ、です。




引用返信 編集キー/
■9877 / inTopicNo.8)  Re[7]: フォルダ監視Windowsサービスのエラー処理
□投稿者/ nbmyou (54回)-(2007/11/06(Tue) 14:51:47)
2007/11/07(Wed) 16:41:14 編集(投稿者)

No9842 (mあ@反省中 さん) に返信

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

> というか、そろそろ、
> OnStart()
> OnStop()
> run()
> 各メソッドの内容を見せてくれてもいいのでは?
>
> これまで色々アドバイスがあったが、どれくらい理解できているのかが知りたいところ、です。

了解しました。
メソッド等を見て、チェックしていただけるととても助かります。ありがとうございます。
後ほど、この投稿を編集してメソッドの内容を有る程度お見せしたいと思います。

ただ、修正の時間とリスクの問題から、
・System.Timers.Timerを使用し、System.Threading.CompareExchange()を使用してシングルスレッドで動作させている。
状態です。

それでは、しばらくお待ちください。
(11/7 なかなか投稿できず、遅れてしまっていて申し訳ありません。明日には投稿できる予定です)
引用返信 編集キー/


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

このトピックに書きこむ

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

管理者用

- Child Tree -