45

ネットワーク サーバー上のフォルダ ツリーの変更を監視したいと考えています。ファイルにはすべて特定の拡張子が付いています。ツリーには約 200 個のフォルダーと、私が見ている拡張子のファイルが約 1200 個あります。

サーバー上で実行するサービスを作成することはできません (立ち入り禁止!) ため、ソリューションはクライアントに対してローカルである必要があります。適時性は特に重要ではありません。通知が1分以上遅れても大丈夫です。作成、削除、名前変更、および変更を監視しています。

.NET System.IO.fileSystemWatcher を使用すると、サーバーに多くの負荷がかかりますか?

監視対象のフォルダー/ファイルの数を減らすために、10 個の個別のウォッチャーはどうですか? (合計で 700 個のフォルダーから 200 個、5500 個のファイルから 1200 個に減少) ネットワーク トラフィックが減少するのではなく増加しますか? 私の考えは、監視対象のファイルを 1 つのツリーの下に配置するためのサーバーの改造です。私は常にこのオプションを持っているとは限らないため、ウォッチャーのチームです。

もう1つの解決策は、FSWがサーバーに過度の負荷をかけているかどうか、またはSysAdminタイプの理由で機能しないかどうかを定期的にチェックすることだと思います.

これを行うより良い方法はありますか?

4

7 に答える 7

76

サーバー負荷の観点から、説明したシナリオでリモート変更通知にIO.FileSystemWatcherを使用することは、おそらく最も効率的な方法です。これは、FindFirstChangeNotificationおよびReadDirectoryChangesW Win32 API 関数を内部的に使用し、最適化された方法でネットワーク リダイレクタと通信します (標準の Windows ネットワークを想定して: サード パーティのリダイレクタが使用され、必要な機能をサポートしていない場合、物事が勝ちます)。まったく機能しません)。.NET ラッパーは、非同期 I/O なども使用するため、最大限の効率が保証されます。

このソリューションの唯一の問題は、信頼性が低いことです。ネットワーク接続が一時的に切断されることに対処する必要があることを除けば (この場合、IO.FileSystemWatcher は処理可能なエラー イベントを発生させるため、それほど問題ではありません)、基礎となるメカニズムには特定の基本的な制限があります。Win32 API 関数の MSDN ドキュメントから:

つまり、負荷が高い場合 (大きなバッファが必要な場合)、またはさらに悪いことに、不特定のランダムな状況では、期待する通知が得られない可能性があります。これは、ローカル ファイル システム ウォッチャーの問題でもありますが、ネットワーク上ではより大きな問題です。SO に関する別の質問では、API に固有の信頼性の問題をもう少し詳しく説明しています。

ファイル システム ウォッチャーを使用する場合、アプリケーションはこれらの制限に対処できる必要があります。例えば:

  • 探しているファイルにシーケンス番号がある場合は、通知を受けた最後のシーケンス番号を保存してください。これにより、今後の通知で「ギャップ」を探し、通知を受け取らなかったファイルを処理できます。

  • 通知を受け取ったら、常に完全なディレクトリ スキャンを実行します。これは非常に悪いように聞こえるかもしれませんが、スキャンはイベント ドリブンであるため、ダム ポーリングよりもはるかに効率的です。また、1 つのディレクトリ内のファイルの総数と、スキャンするディレクトリの数を 1,000 程度以下に抑えている限り、この操作がパフォーマンスに与える影響はとにかく最小限に抑える必要があります。

複数のリスナーを設定することは、可能な限り避けるべきことです。どちらかといえば、これにより信頼性がさらに低下します...

とにかく、絶対ファイル システム ウォッチャーを使用する必要がある場合は、制限を認識している限り問題なく機能し、変更/作成されたすべてのファイルに対して 1 対 1 の通知を期待しないでください。

したがって、他のオプションがある場合 (基本的に、ファイルを書き込むプロセスが非ファイル システム ベースの方法で通知するようにします。通常の RPC メソッドは改善されます...)、それらは信頼性の点から検討する価値があります。ビューの。

于 2008-09-30T06:00:47.927 に答える
10

私はC#のファイルシステムウォッチャーを何度も使用しました。初めて使用したときは、主に変更を報告したスレッドで変更を処理していたために、機能しなくなるという問題が発生しました。

ただし、変更をキューにプッシュして、別のスレッドでキューを処理するだけです。これは私が最初に抱えていた問題を解決するようです。あなたの問題では、複数のウォッチャーが同じキューにプッシュする可能性があります。

しかし、私はあなたのような規模の問題でこれを使用していません。

于 2008-09-30T20:07:43.787 に答える
3

私の経験では、FSW が高いネットワーク トラフィックを作成することはありません。ただし、パフォーマンスの問題がある場合は、複数のウォッチャーを使用し、監視対象のフォルダー数を少なくするというアプローチは妥当に思えます。

ただし、ネットワーク ドライブ上の FSW にはいくつかの大きな問題がありました。ファイルを削除すると、常にエラー イベントが発生し、削除されたイベントは発生しませんでした。解決策が見つからなかったので、回避策があれば FSW の使用を避けるようになりました...

于 2008-10-03T11:09:14.430 に答える
2

MSDNのドキュメントには、FileSystemWatcher コンポーネントを使用して、ネットワークドライブ上のファイル システムの変更を監視できることが示されています。

また、ウォッチャー コンポーネントが、ターゲット ドライブに定期的に変更の問い合わせを行うのではなく、ファイル システムの変更通知をリッスンしていることも示しています。

それに基づいて、ネットワークトラフィックの量は、そのネットワークドライブの内容がどれだけ変化すると予想されるかに完全に依存します. FSW コンポーネントは、ネットワーク トラフィックのレベルを増加させません。

于 2008-09-30T05:31:16.610 に答える
1

System.IO.FileSystemWatcher をしばらく使用した後。あまりにも速く発生するイベントを処理するのに十分なほど安定していません。ファイルの 100% 読み取りを保証するため。ファイルを検索するには、単純なディレクトリ メソッドを使用します。読み終わったら、すぐにファイルを別のフォルダにコピーしてください。ファイルの読み取り中に追加される新しいファイルからそれを分離するため。

タイマーは、フォルダーを定期的に読み取るために使用されます。既に読み込まれたファイルをアーカイブ フォルダにコピーすることで、再度読み込まれないようにします。その後の読み取りは常に新しいファイルになります。

var fileNames = Directory.GetFiles(srcFolder);
foreach (string fileName in fileNames)
{
   string[] lines = File.ReadAllLines(fileName);
}
于 2016-05-27T06:52:31.027 に答える
1

ウォッチャーは 100% 信頼できるように見えます。ウォッチャー オブジェクトのバッファー サイズを確認してください。何千ものファイル更新をテストしましたが、失われたものはありません。

マルチスレッド アプローチを使用することをお勧めします。トリガーはファイル ウォッチャーです。検出されたファイル変更ごとにスレッドを起動できます。ウォッチャーは、オーバーフローの可能性が少なく、はるかに高速に処理できます。(非同期スレッドを使用)

于 2014-09-24T17:13:23.243 に答える
-1

FSW を搭載したコンピュータと位置が監視されているコンピュータとの間で、何らかのアクティブな状態や通信が行われているとは思えません。つまり、FSW はネットワーク化された OS に ping を送信してファイルをチェックしていません。

メッセージまたはイベントは、変更が発生したときにネットワーク化された FSW にのみ発生/送信されると想像できます。

しかし、これはすべて憶測にすぎません。:)

于 2008-09-30T05:08:42.247 に答える