選択したフォルダーで* .logファイルをリッスンするアプリがあります。 FileSystemWatcher
を使用しました。
しかし問題がある。そのファイルの作成を担当する他のアプリは、次の手順を実行します。
そして、私はこの振る舞いを変えることはできません。
そこで、*。gzファイルと* .txtファイル用に2つのFileSystemWatcher
sを作成しました。どうして?このアプリはgzファイルを解凍しない場合や、txtファイルの名前を最終的な* .logファイルに変更しない場合があるためです。
_FileSystemWatcher2
_はtxtファイルをキャッチし、(ほとんどの場合、次の1000ミリ秒でログインするように名前が変更されます)txtファイルが存在するかどうかを確認するためにしばらく待つ必要があります(存在しない場合は、最後の名前に変更されているようです* .logファイル)。
問題は、UIのフリーズを防ぐためにThread.Sleep()
なしでファイルが存在するかどうかを確認する方法です。
私はそれが明確であることを願っています、そうでなければ私はそれをよりよく説明しようとします。これは複雑な問題だと思います。
いくつかのコードサンプル:
Gzファイルのウォッチャー:
_private void fileSystemWatcher_Created(object sender, FileSystemEventArgs e)
{
//this is for gz files in case if gz file is not unpacked automatically by other app
//I need to wait and check if gz was unpacked, if not, unpack it by myself,
//then txt watcher will catch that
Thread.Sleep(5000);
if (File.Exists(e.FullPath))
{
try
{
byte[] dataBuffer = new byte[4096];
using (System.IO.Stream fs = new FileStream(e.FullPath,
FileMode.Open,
FileAccess.Read))
{
using (GZipInputStream gzipStream = new GZipInputStream(fs))
{
string fnOut = Path.Combine(path_to_watcher,
Path.GetFileNameWithoutExtension(e.FullPath));
using (FileStream fsOut = File.Create(fnOut))
{
StreamUtils.Copy(gzipStream, fsOut, dataBuffer);
}
}
}
}
catch { //Ignore }
}
}
_
Txtファイルのウォッチャー:
_private void fileSystemWatcher2_Created(object sender, FileSystemEventArgs e)
{
//this is for txt file
Thread.Sleep(3500);
if (File.Exists(e.FullPath))
{
//make my actions
}
else
{
//make my actions
}
}
_
実際には、FileSystemWatcher。NET自体によって別のスレッドで呼び出される作成されたイベント..したがって、基本的にまったく何もする必要はありません。あなたのコードはそのままでOKです。
これがその証拠です:
class Program
{
static void Main(string[] args)
{
FileSystemWatcher fw = new FileSystemWatcher(@"C:\temp");
fw.Created += fileSystemWatcher_Created;
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
fw.EnableRaisingEvents = true;
Console.ReadLine();
}
static void fileSystemWatcher_Created(object sender, FileSystemEventArgs e)
{
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
}
}
BackGroundWorker を使用してファイルシステムを監視し、UIのフリーズを回避できます
UIスレッドをロックせずにスリープを使用できます。基本的に、別のスレッドをスリープします。
public event EventHandler FileCreated;
public void CheckFileExists()
{
while(!File.Exists(""))
{
Thread.Sleep(1000);
}
FileCreated(this, new EventArgs());
}
次に、これを次のように呼び出します。
Thread t = new Thread(CheckFileExists);
this.FileCreated += new EventHandler(somemethod);
t.Start();
public void SomeMethod(object sender, EventArgs e)
{
MessageBox.Show("File Created!");
}
または、別の投稿で言及されているように、別のスレッドの代わりにBackGroundWorker
を使用し、言及したコードをDoWork
に入れて、OnFinish
イベントをリッスンしますが、ないので確認しますどちらの方法でも、それだけの作業で問題ありません。
int i = 0;
while (!File.Exists && i < 30) //limit the time to whait to 30 sec
{
Threed.Sleep(1000);
File.Refresh();
i++;
}