ローカルまたはネットワークドライブ上のディレクトリに作成されるファイルを監視するアプリケーションをセットアップする必要があります。
でしょうFileSystemWatcher
かポーリングタイマーには最良の選択肢でしょう。私は過去に両方の方法を使用しましたが、広範囲ではありません。
どちらの方法にもどのような問題(パフォーマンス、信頼性など)がありますか?
ローカルまたはネットワークドライブ上のディレクトリに作成されるファイルを監視するアプリケーションをセットアップする必要があります。
でしょうFileSystemWatcher
かポーリングタイマーには最良の選択肢でしょう。私は過去に両方の方法を使用しましたが、広範囲ではありません。
どちらの方法にもどのような問題(パフォーマンス、信頼性など)がありますか?
回答:
実稼働環境とテスト環境でファイルシステムウォッチャーが失敗するのを見てきました。今では便利だと思いますが、信頼できるとは思いません。私のパターンは、ファイルシステムウォッチャーで変更を監視することでしたが、欠落しているファイルの変更を検出するために時々ポーリングします。
編集:UIがある場合は、ポーリングの代わりに変更を「更新」する機能をユーザーに与えることもできます。これをファイルシステムウォッチャーと組み合わせます。
私が抱えていた最大の問題は、バッファがいっぱいになったときにファイルが見つからないことです。簡単に修正できます。バッファを増やすだけです。ファイル名とイベントが含まれているので、予想されるファイル数(試行とエラー)まで増やしてください。ページアウトできないメモリを使用するため、メモリが不足すると、他のプロセスにページングを強制する可能性があります。
これがバッファに関するMSDNの記事 です。FileSystemWatcher.. ::。InternalBufferSizeプロパティ
MSDNごと:
バッファーサイズの増加は、ディスクにスワップアウトできない非ページメモリが原因であるため、コストがかかるため、バッファーをできるだけ小さくしてください。バッファオーバーフローを回避するには、NotifyFilterプロパティとIncludeSubdirectoriesプロパティを使用して、不要な変更通知を除外します。
一度に大量のバッチが予想されるため、16MBを使用します。正常に動作し、ファイルを見逃すことはありません。
また、1つでも処理を開始する前にすべてのファイルを読み取ります...ファイル名を安全に(この場合はデータベーステーブルに)キャッシュしてから、処理します。
ファイルのロックの問題については、ファイルのロックが解除されるまで1秒、2秒、4回と待機するプロセスを生成します。私たちは決してポーリングしません。これは約2年間エラーなしで生産されています。
またFileSystemWatcher
、キューに入れられた変更の数が提供されたバッファをオーバーフローすると、ビジー時に変更が失われる可能性もあります。これは.NETクラス自体の制限ではなく、基盤となるWin32インフラストラクチャの制限です。私たちの経験では、この問題を最小限に抑える最善の方法は、通知をできるだけ早くデキューして、別のスレッドで処理することです。
上記の@ChillTempで述べたように、ウォッチャーはWindows以外の共有では機能しない場合があります。たとえば、マウントされたNovellドライブではまったく機能しません。
見落とされた変更をピックアップするために時々投票を行うことが、適切な妥協案であることに同意します。
また、ファイルシステムウォッチャーは、ファイル共有では信頼できないことに注意してください。特に、ファイル共有がWindows以外のサーバーでホストされている場合。FSWは重要なものには使用しないでください。または、何も見落とされていないことを確認するために時々ポーリングを使用する必要があります。
私は現在FileSystemWatcher
、平均で100ミリ秒ごとに更新されるXMLファイルでを使用しています。
FileSystemWatcher
が正しく設定されている限り、ローカルファイルに問題が発生することはありません。
リモートファイルウォッチやWindows以外の共有の経験はありません。
あなたが本質的に不信感を持っているFileSystemWatcher
か、ここにいる他のすべての人がリストしている制限(Windows以外の共有、およびリモートファイル監視)を直接経験していない限り、ファイルのポーリングは冗長でオーバーヘッドの価値がないと考えます。
FileSystemWatcher
ネットワーク共有での使用で問題が発生しました。純粋なWindows環境の場合は問題ないかもしれませんが、NFS共有を監視していました。NFSはステートレスであるため、監視しているファイルが変更されたときに通知がありませんでした。
私の意見では、FSW とポーリングの両方を使用することは時間とリソースの浪費であり、経験豊富な開発者がそれを提案することに驚いています。ポーリングを使用して「FSWミス」をチェックする必要がある場合は、当然、FSWをすべて破棄して、ポーリングのみを使用できます。
現在、開発中のプロジェクトにFSWを使用するか、ポーリングを使用するかを決定しようとしています。回答を読むと、FSWがニーズを完全にカバーしている場合もあれば、ポーリングが必要な場合もあることは明らかです。残念ながら、実際にはパフォーマンスの違い(存在する場合)については回答がなく、「信頼性」の問題についてのみ対処しています。質問のその部分に答えることができる人はいますか?
編集: FSWとポーリングの両方を使用することの妥当性に関するnmcleanのポイント(興味があれば、コメントの議論を読むことができます)は、FSWとポーリングの両方を使用する状況があり得る理由が非常に合理的な説明のようです効率的です。nmclean、私(および同じ意見を持つ人)に光を当ててくれてありがとう。
変更の代わりに作成イベントを操作するための実用的なソリューション
コピー、切り取り、貼り付け、移動も可能です。
class Program
{
static void Main(string[] args)
{
string SourceFolderPath = "D:\\SourcePath";
string DestinationFolderPath = "D:\\DestinationPath";
FileSystemWatcher FileSystemWatcher = new FileSystemWatcher();
FileSystemWatcher.Path = SourceFolderPath;
FileSystemWatcher.IncludeSubdirectories = false;
FileSystemWatcher.NotifyFilter = NotifyFilters.FileName; // ON FILE NAME FILTER
FileSystemWatcher.Filter = "*.txt";
FileSystemWatcher.Created +=FileSystemWatcher_Created; // TRIGGERED ONLY FOR FILE GOT CREATED BY COPY, CUT PASTE, MOVE
FileSystemWatcher.EnableRaisingEvents = true;
Console.Read();
}
static void FileSystemWatcher_Created(object sender, FileSystemEventArgs e)
{
string SourceFolderPath = "D:\\SourcePath";
string DestinationFolderPath = "D:\\DestinationPath";
try
{
// DO SOMETING LIKE MOVE, COPY, ETC
File.Copy(e.FullPath, DestinationFolderPath + @"\" + e.Name);
}
catch
{
}
}
}
静的ストレージを使用したファイル属性変更イベント中のこのファイルウォッチャーの解決策
class Program
{
static string IsSameFile = string.Empty; // USE STATIC FOR TRACKING
static void Main(string[] args)
{
string SourceFolderPath = "D:\\SourcePath";
string DestinationFolderPath = "D:\\DestinationPath";
FileSystemWatcher FileSystemWatcher = new FileSystemWatcher();
FileSystemWatcher.Path = SourceFolderPath;
FileSystemWatcher.IncludeSubdirectories = false;
FileSystemWatcher.NotifyFilter = NotifyFilters.LastWrite;
FileSystemWatcher.Filter = "*.txt";
FileSystemWatcher.Changed += FileSystemWatcher_Changed;
FileSystemWatcher.EnableRaisingEvents = true;
Console.Read();
}
static void FileSystemWatcher_Changed(object sender, FileSystemEventArgs e)
{
if (e.Name == IsSameFile) //SKIPS ON MULTIPLE TRIGGERS
{
return;
}
else
{
string SourceFolderPath = "D:\\SourcePath";
string DestinationFolderPath = "D:\\DestinationPath";
try
{
// DO SOMETING LIKE MOVE, COPY, ETC
File.Copy(e.FullPath, DestinationFolderPath + @"\" + e.Name);
}
catch
{
}
}
IsSameFile = e.Name;
}
}
これは、この複数のトリガーイベントの問題の回避策です。
特に「制御されていない」fswイベントに依存するよりも、ポーリングイベントがトリガーされたときにファイルの存在をモック/スタブ化する方がはるかに簡単なので、特にTDDシナリオではポーリングを使用すると思います。+ fswエラーに悩まされていた多くのアプリに取り組んできたことに。