Как подождать до File.Exists?

У меня есть приложение, которое прослушивает файл *.log в выбранной папке. Я использовал FileSystemWatcher.

Но есть проблема. Другое приложение, ответственное за создание этого файла, выполняет следующие шаги:

  • Создайте файл *.gz
  • Распакуйте его в txt файл (некоторое произвольное имя файла)
  • Измените имя *.txt на правильное с расширением *.log.

И я не могу изменить это поведение.

Итак, я сделал 2 FileSystemWatcher для *.gz и *.txt файлов. Зачем? Поскольку это приложение иногда не распаковывает gz файл и иногда не переименовывает txt файл в окончательный файл *.log.

FileSystemWatcher2 улавливает txt файл, затем (в большинстве случаев он переименовывается для входа в следующие 1000 мс). Мне нужно подождать некоторое время, чтобы проверить, существует ли файл txt (если нет, он, кажется, переименован в окончательный *.журнальный файл).

Вопрос в том, как проверить, существует ли файл без 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
   }
}

Ответ 1

Фактически 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);
    }
}

Ответ 2

Вы можете использовать BackGroundWorker для мониторинга файловой системы - и не замораживать свой интерфейс пользователя

Ответ 3

Вы можете использовать сон без блокировки потока пользовательского интерфейса, вы, по сути, спятите отдельный поток.

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, но видя, что не так много работы для выполнения методы прекрасны.