2010-12-27 68 views
5

他のアプリケーションを起動するアプリケーションがあり、特定のデータファイルを作成するのを待っています(同時に1つのアプリケーションを監視しています)。アプリケーションが起動されるたびに、特定のディレクトリが作成される特定のファイルを監視します。私はこれを行うFileSystemWatcherを使用しています(それをディレクトリに設定してから、正しいファイル名をフィルタリングしてください)。これは最初(常に)素晴らしいですが、2番目のアプリケーションを起動してもイベントは発生しません。イベントを発生させる唯一の方法は、イベントハンドラにブレークポイントを設定するか、イベントハンドラにThread.Sleepコマンドがあるかどうかです。これは私にとっては非常に奇妙なようです...私が気づいていない競合状態はありますか?ここにコードがあります。私はThread.Sleep(500)を持っていることに注意してください。このコードでは、毎回コードが動作します。それがなければ失敗するでしょう。私は本当にスリープコマンドに頼らず快適です。どのような状態でもうまくいかない原因になるかどうかはわかりません。FileSystemWatcher - イベントが2回目に起動しない

public static void watchFiles(string path) 
    { 
     FileSystemWatcher watcher = new FileSystemWatcher(); 
     watcher.Path = path; 
     watcher.Created += new FileSystemEventHandler(watcher_Handler); 
     watcher.EnableRaisingEvents = true; 
    } 

    public static void watcher_Handler(object sender, FileSystemEventArgs e) 
    { 
     //Hack - the sleep allows the second and third application to be caught by this event 
     Thread.Sleep(500); 

     switch (e.ChangeType.ToString()) 
     { 
      case "Changed": 
       break; 
      case "Deleted": 
       break; 
      case "Created": 
       if (e.Name == "log.dat") 
       { 
        parseDataFile(); 
        moveHTMLtoLMS(); 

       } 
       break; 
      default: 
       break; 
     } 
    } 

コードをもう一度動作させるには、なぜスリープ(またはブレークポイント)する必要があるのですか?

+0

このコードは私にとっては大丈夫です。 – Simone

+5

注:スイッチで 'e.ChangeType.ToString()'を使う必要はありません。 'e.ChangeType'をオンにして、' ChangeType.XXX'を作るだけです。これにより、厳密に型付けされ、エラーが発生しにくくなります。 – Femaref

+0

ファイルシステムウォッチャーには多くの警告があるようです。 http://msdn.microsoft.com/en-us/library/system.io.filesystemwatcher.oncreated.aspx つまり、さまざまなウォッチャーが同じディレクトリを監視していないことは確かですか? – NotMe

答えて

1

System.IO.FileSystemWatcherクラスのドキュメントによると:

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

イベントが十分に速く消費されておらず、内部バッファーがすべての通知を処理するのに十分な大きさではない可能性があります。既定では、ウォッチャーはFileNameDirectoryNameLastWriteの通知を処理しますが、作成イベント(ファイルとディレクトリの両方)のみを消費します。あなたのアプリケーションはすばやく連続して動作していますか?私はあなたのアプリケーション(イベントハンドラの代わりに)の呼び出しの間に遅延を入れようとするより具体的なフィルタを使用して(Filterプロパティを使用してログファイルのみを通知または監視するだけでFileName)、内部バッファサイズを増やすか、上記の私はそれがあなたの問題を解決すべきだと思います。

+1

他のアプリケーションはすばやく連続して実行されていません。私は、同じ結果を持つ異なるアプリケーションを起動するまで数秒か数分待つことができます。 – cwo

+0

@cwo:あなたが言及した他のことを試してみると、遅れを取り去って逃げることができるかもしれません。 –

0

「作成済み」イベントは1つだけリスンしています。 OnChanged、OnDeleted - http://msdn.microsoft.com/en-us/library/system.io.filesystemwatcher.aspx

EDIT:ほとんどのプログラムは、すでにファイルが存在する場合、ファイルを作成しません。 FileMon(現在のプロセスモニタ - http://technet.microsoft.com/en-us/sysinternals/bb896645)を使用して、各プログラムがファイルで実行する操作を確認することができます。

+0

私が興味を持っているのは作成したイベントだけです。switch文の他のケースは、最初にファイルシステムウォッチャーをテストするためのものでした。ファイルが作成されるとき、私はそれを解析する必要があります。それがファイルを操作する方法は決して変更、削除、または名前変更されません(または私がそれについて気にしない場合)。 – cwo

+0

プロセスモニターを使用して、前提条件を確認してみてください - 他のプログラムで "作成"操作がないと思われます...または、少なくとも問題は通知ではなくコードであることがわかります。 –

+0

ファイルが正しい場所に作成されていることを確認しました。私はプロセスエクスプローラを使用しています。しかし、問題のディレクトリを開いてファイルが作成されていることを確認することもできます。 – cwo

0

私はまったく同じ問題に直面しています(Windows XPを実行中)。あなたのハックは問題を解決します。私は関連性のあるメモを追加したいと思います。

私の場合、ファイル名は常に同じです.C:\ blah.txtが作成、削除、作成されます。私はあなたの睡眠ハックを追加するとき

Integrator.StartMonitor(); // Start the file monitor! 

Form f = new Form(); 
f.ShowInTaskbar = false; 
f.ShowIcon = false; 
f.StartPosition = FormStartPosition.Manual; 
f.Location = new Point(-32000, -32000); 

f.Show(); 
f.Hide(); 

Application.Run(); 

マイファイルウォッチャーは、デバッグモードで動作しますか:また、私は自分のアプリケーションを非表示にするトリックを使用しています。確かにFileSystemWatcherのバグのように見えます。

1
public static void watchFiles(string path) 
{ 
    FileSystemWatcher watcher = new FileSystemWatcher(); 
    watcher.Path = path; 
    watcher.Created += new FileSystemEventHandler(watcher_Handler); 
    watcher.EnableRaisingEvents = true; 
} 

watcher変数は、このメソッドの最後にガベージコレクションの対象となります。ローカル変数ではなく、次のようなクラスレベルメンバにしてください。

private static FileSystemWatcher watcher; 

public static void watchFiles(string path) 
{ 
    if (watcher != null) 
    { 
     watcher.EnableRaisingEvents = false; 
     watcher.Created -= new FileSystemEventHandler(watcher_Handler); 
    } 

    watcher = new FileSystemWatcher(); 
    watcher.Path = path; 
    watcher.Created += new FileSystemEventHandler(watcher_Handler); 
    watcher.EnableRaisingEvents = true; 
} 
関連する問題