13

ネットワーク ディレクトリを監視し、Windows Server 2008 マシンで実行するツールを作成しています。FileSystemWatcher の OnChanged イベントは、Windows 7 を使用していないコンピューターによってネットワーク ドライブに配置されたファイルから正しく起動されています。コピーされたファイルの量が Windows 7 コンピューターで (一度に) 19 を超える場合、イベントは発生しませんが、ファイルが個別に実行された場合は機能します。これに対する回避策はありますか、それとも Windows 7 カーネルが FSW イベントでどのように動作するかということですか?

XPマシンからコピーした場合、何千ものファイルに対して機能することを明確にするために。(ソフトウェアはまだ 2008 サーバー マシンにあります)。

4

5 に答える 5

22

MSDNから:

Windows オペレーティング システムは、FileSystemWatcher によって作成されたバッファー内のファイルの変更をコンポーネントに通知します。短時間に多くの変更がある場合、バッファがオーバーフローする可能性があります。これにより、コンポーネントはディレクトリ内の変更を追跡できなくなり、一括通知のみが提供されます。InternalBufferSizeプロパティを使用してバッファーのサイズを大きくすると、ディスクにスワップ アウトできない非ページ メモリに由来するため、負荷が高くなります。そのため、ファイル変更イベントを見逃さないように、バッファーをできるだけ小さく保ちます。バッファ オーバーフローを回避するには、NotifyFilterプロパティとIncludeSubdirectoriesプロパティを使用して、不要な変更通知を除外できるようにします。

バッファー サイズを増やすだけでは不十分で、一度にイベントをトリガーするファイルの数を制御できない場合は、追加のポーリングを追加する必要があります。

この関連する質問も参照してください。

多くのファイルが同時にディレクトリに追加されると、FileSystemWatcher が正しく動作しません…</a>

アップデート:

単純にバッファ サイズを増やしたくなるかもしれませんが、これは慎重に行う必要があります。実際、ネットワーク アクセスに関しては 64k の制限があります。クラスは、FileSystemWatcherReadDirectoryChangesWこの制限があるWindows API 関数を使用しています。

バッファー長が 64 KB を超え、アプリケーションがネットワーク経由でディレクトリを監視している場合、ReadDirectoryChangesW は ERROR_INVALID_PARAMETER で失敗します。これは、基盤となるファイル共有プロトコルのパケット サイズの制限によるものです。

バッファ サイズを変更するコストについてより深く理解したい場合は、Microsoft の Walter Wang の投稿をご覧ください。

ネットワーク全体の FileSystemWatcher (完全な投稿を以下に引用)

申し訳ありませんが、FileSystemWatcher.InternalBufferSize のドキュメントには、ネットワーク パスを監視するときのバッファ サイズについて明確に記載されていませんでした。ネットワーク パスを監視する場合は、64K を超えないようにすることをお勧めします。

FileSystemWatcher は基本的に、Win32 ReadDirectoryChangesW API の .Net ラッパーです。ReadDirectoryChangesW を使用するには、OS が変更を取り込むバッファーを作成して指定します。ただし、ReadDirectoryChangesW のドキュメントには記載されていませんが (ただし、FileSystemWatcher のドキュメントにはヒントが示されています)、ファイル システムが内部カーネル バッファーを作成して、ユーザー バッファーを更新する機会が得られるまで変更情報を一時的に保存するということです。作成されるカーネル バッファーのサイズは、ReadDirectoryChangesW で指定されたサイズと同じであり、非ページ プール メモリに作成されます。FileSystemWatcher / ReadDirectoryChangesW が作成または呼び出されるたびに、新しいカーネル バッファーも作成されます。

カーネル メモリ プール (ページおよび非ページ) は、デバイス ドライバーおよびその他のカーネル コンポーネントが使用するためにシステム アドレス空間に確保されます。必要に応じて動的に拡大および縮小します。プールの現在のサイズは、タスク マネージャーの [パフォーマンス] タブで簡単に確認できます。プールは、ブート時に計算され、使用可能なシステム リソース (主に RAM) に依存する最大値に達するまで、動的に拡張されます。この最大値に達したくない場合は、さまざまなシステム サービスとドライバーが失敗し始めます。ただし、この計算された最大値は簡単には入手できません。最大プール サイズを確認するには、カーネル デバッガーを使用する必要があります。システム メモリ プールの詳細については、

これを念頭に置いて、使用できるバッファーのサイズに関する推奨事項はありません。システム プールの現在のサイズと最大サイズは、クライアントごとに異なります。ただし、FileSystemWatcher / ReadDirectoryChangesW バッファーごとに 64k を超えないようにする必要があります。これは、ReadDirectoryChangesW に記載されているように、ネットワーク アクセスに 64k の制限があることに起因します。しかし最終的には、バッファを調整できるように、予想されるさまざまなターゲット システムでアプリケーションをテストする必要があります。

.Net アプリケーションに関連するオーバーヘッドがあり、Win32 ReadDirectoryChangesW プログラムは同じバッファー サイズでより良いパフォーマンスを達成できると思います。ただし、非常に高速で多数のファイル変更がある場合、バッファ オーバーランは避けられず、開発者はディレクトリを手動で列挙して変更を検出するなど、オーバーランが発生した場合に対処する必要があります。

結論として、FileSystemWatcher と ReadDirectoryChangesW は軽量のファイル変更検出メカニズムであり、制限があります。変更ジャーナルは、中規模のソリューションと考えられるもう 1 つのメカニズムですが、それでも制限があります。

http://msdn.microsoft.com/en-us/library/aa363798%28VS.85%29.aspx

負荷の高いソリューションは、ファイル システム スタックに常駐し、ファイル システムの変更を監視する専用のファイル システム フィルター ドライバーを作成することです。もちろん、これは最も複雑なアプローチです。ほとんどのウイルス スキャナ、バックアップ ソフトウェア、および filemon (www.sysinternals.com) などのファイル システム監視ユーティリティは、フィルタ ドライバを実装しています。

上記の説明が、発生している問題の根本原因を理解するのに役立つことを願っています。さらに情報が必要かどうかをお知らせください。ありがとうございました。

于 2010-07-14T20:56:21.710 に答える
4

FileSystemWatcher を使用して何度も試みた後、あきらめました。間違ったタイミングで、間違ったタイプのイベントを正しく起動しません。正直なところ、これは .net フレームワークで最悪のクラスの 1 つだと思います。私は常に System.Timer を使用する独自のクラスを作成することになり、x ミリ秒が経過した後、ディレクトリ、ファイルを手動でチェックします。はい、より多くの作業が必要です。はい、わずかな PITA になる可能性がありますが、一度作成すると、どこでも使用できます。FileSystemWatcher が宣伝どおりに機能することを望みますが、そのように機能することはありません。

于 2010-07-14T21:14:35.903 に答える
2

FileSystemWatcher イベントが発生した場合、ほとんどの場合、このリストが不完全である可能性があるため、オブジェクトによって渡されるファイルを無視します。

FileSystemWatcher オブジェクトが監視しているディレクトリをクロールし、手動スキャンを実行して、FileSystemWatcher バッファーにない可能性のあるファイルを見つけるだけです。それほどエレガントではありませんが、ファイルを見逃すことはありません。

于 2010-07-14T21:18:39.347 に答える
0

これは本当に信頼性の低いクラスの1つです。ファイルが特定のしきい値を超えると、最初のコピーでイベントが約7回発生し、ファイル転送ダイアログが完了すると、さらに7つのイベントが発生します。この問題は、すべてのOSで発生します。 FSWをサポートします。Windows 7(まだvistaを試していません)はまだ一度に1つまたは19のファイルしか受け入れませんが、XPマシンからネットワークドライブにファイルをドロップすると、何千ものファイルを一度に問題なく読み取ることができます。これは、ReadDirectoryChangesWをXPから7に変更しただけの可能性があります。過去19ファイルでは、イベントを発生させることができなかったため、今のところ、これがツールの「機能」になると思います。他の情報があれば、遠慮なく投稿してください。

于 2010-07-27T04:59:34.070 に答える