我有一个应用程序,在所选文件夹中侦听* .log文件。我使用了FileSystemWatcher
。
但是有一个问题。负责制作该文件的另一个应用程序采取以下步骤:
我无法改变这种行为。
所以我为* .gz和* .txt文件制作了2 FileSystemWatcher
s。为什么?因为此应用程序有时不解压缩gz文件,有时不会将txt文件重命名为最终的* .log文件。
FileSystemWatcher2
捕获txt文件,然后(在大多数情况下,它被重命名为在接下来的1000毫秒内登录)我需要等待一段时间来检查是否存在txt文件(如果没有,它似乎被重命名为最终的* .log文件)。
问题是,如何在没有Thread.Sleep()
的情况下检查文件是否存在以防止UI冻结?
我希望很清楚,如果不是,我会尝试更好地描述它。我认为这是一个复杂的问题。
一些代码示例:
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
}
}
答案 0 :(得分:9)
实际上FileSystemWatcher 由.NET本身在单独的线程中调用创建的事件 ..所以基本上你绝对不需要做什么。你的代码没问题。
以下是证据:
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);
}
}
答案 1 :(得分:3)
您可以使用BackGroundWorker来监控文件系统 - 并避免冻结您的用户界面
答案 2 :(得分:2)
你可以在不锁定UI线程的情况下使用sleep,你基本上可以睡一个单独的线程。
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
事件,但是看不到做任何一种方法的工作都很好。
答案 3 :(得分:0)
int i = 0;
while (!File.Exists && i < 30) //limit the time to whait to 30 sec
{
Threed.Sleep(1000);
File.Refresh();
i++;
}