如何等到File.Exists?

我有一个应用程序,在所选文件夹中侦听* .log文件。 我用过FileSystemWatcher

但有一个问题。 负责制作该文件的另一个应用程序采取以下步骤:

  1. 制作一个* .gz文件
  2. 将其解压缩到txt文件(一些随机文件名)
  3. 将* .txt名称更改为具有* .log扩展名的正确名称。

我无法改变这种行为。

所以我为* .gz和* .txt文件制作了2个FileSystemWatcher 。 为什么? 因为此应用程序有时不解压缩gz文件,有时不会将txt文件重命名为最终的* .log文件。

FileSystemWatcher2捕获txt文件,然后(在大多数情况下,它被重命名为在接下来的1000ms内登录)我需要等待一段时间来检查txt文件是否存在(如果没有,它似乎被重命名为最终的* .log文件) 。

问题是,如何在没有Thread.Sleep()情况下检查文件是否存在以防止UI冻结?

我希望很清楚,如果不是,我会尝试更好地描述它。 我认为这是一个复杂的问题。

一些代码示例:

Watz for 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 } } } 

Watger for 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本身在单独的线程中调用 。所以基本上你绝对不需要做什么 。 你的代码没问题。

这是certificate:

 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线程的情况下使用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事件,但是看到没有那么多的工作要做,两种方法都没问题。

 int i = 0; while (!File.Exists && i < 30) //limit the time to whait to 30 sec { Threed.Sleep(1000); File.Refresh(); i++; }