title: Directory.GetFiles fails with error The process cannot access the file because it is being used by another process
body: <p>My code is </p>
  
  <pre><code>var files = Directory.GetFiles(this.DirectoryPath, this.File.FileMatchPattern, SearchOption.TopDirectoryOnly);
  </code></pre>
  
  <p>Where File.FileMatchPattern looks something like "FileName*.csv" and DirectoryPath is a unc share.</p>
  
  <p>In dev this code executes fine but in uat we're getting the following exception:</p>
  
  <pre><code>ERROR 8 Guggenheim.Pipeline.Services.FileWatcher.WatchedFile - CheckForFile
  System.IO.IOException: The process cannot access the file '\\il1tstbrsapp01\prodapps\FileWatcher\EPAMFileWatcherDropFolderTest\20140531_0171' because it is being used by another process.
     at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
     at System.IO.FileSystemEnumerableIterator`1.CommonInit()
     at System.IO.FileSystemEnumerableIterator`1..ctor(String path, String originalUserPath, String searchPattern, SearchOption searchOption, SearchResultHandler`1 resultHandler, Boolean checkHost)
     at System.IO.Directory.GetFiles(String path, String searchPattern, SearchOption searchOption)
     at Guggenheim.Pipeline.Services.FileWatcher.WatchedFile.CheckForFile() in e:\VS\FixedIncome\Pipeline.Services\Guggenheim.Pipeline.Services.FileWatcher\Guggenheim.Pipeline.Services.FileWatcher\WatchedFile.cs:line 71
  </code></pre>
  
  <p>The weird thing is the path of the error is a directory not a file, it should be noted that that directory is being watched by a FileSystemWatcher.</p>
  
  <p>I don't really care if the file is being accessed by another process, I just want to know if its there at this point. Is there any way to search a directory for files in .NET/C# without caring about locks?</p>
  
  <p>Edit:
  I'm watching the folder with the following code:</p>
  
  <pre><code>Watcher = new FileSystemWatcher(group.WatchDirectory);
              Watcher.IncludeSubdirectories = true;
              Watcher.NotifyFilter = NotifyFilters.DirectoryName;
              Watcher.Created += Watcher_Created;
              WatchedGroups = new List&lt;WatchedGroup&gt;();
              Watcher.EnableRaisingEvents = true;
  </code></pre>
  
  <p>Then on folder created:</p>
  
  <pre><code>private void Watcher_Created(object sender, FileSystemEventArgs e)
      {
          WatchedGroup group = new WatchedGroup(Group, e.FullPath);
          if (group.IsGroupReady)
              group_GroupReady(group, new EventArgs());
          else
          {
              group.GroupFailed += group_GroupFailed;
              group.GroupReady += group_GroupReady;
              WatchedGroups.Add(group);
          }
      }
  </code></pre>
  
  <p>WatchedGroup is the following:</p>
  
  <pre><code>public class WatchedGroup : IDisposable
  {
      public FileWatcherGroup Group { get; private set; }
      private Timer GroupTimer { get; set; }
      public List&lt;WatchedFile&gt; Files { get; private set; }
      public string DirectoryPath { get; private set; }
      public event EventHandler GroupReady;
      public event EventHandler GroupFailed;
      public bool IsGroupReady { get; private set; }
      private readonly object sync = new object();
      public WatchedGroup(FileWatcherGroup group, string directory)
      {
          this.Group = group;
          this.GroupTimer = new Timer(Group.WaitTimeInMinutes * 60000);
          this.GroupTimer.Elapsed += GroupTimer_Elapsed;
          this.DirectoryPath = directory;
          Files = Group.Files.Select(f =&gt; new WatchedFile(f, directory)).ToList();
          CheckGroupReady();
          if (IsGroupReady)
              return;
          foreach(var file in Files)
          {
              file.FileAvailable += File_FileAvailable;
          }
          this.GroupTimer.Start();
      }
      private void StopFiles()
      {
          foreach(var file in Files)
          {
              file.Stop();
          }
          this.GroupTimer.Stop();
      }
      private void CheckFiles()
      {
          foreach(var file in Files.Where(f =&gt; !f.IsFileAvailable))
          {
              file.CheckForFile();
          }
      }
      private void CheckGroupReady()
      {
          lock (sync)
          {
              if (!IsGroupReady &amp;&amp; Files.All(f =&gt; f.IsFileAvailable))
              {
                  IsGroupReady = true;
                  StopFiles();
                  if (GroupReady != null)
                      GroupReady(this, new EventArgs());
  
              }
          }
      }
      private void File_FileAvailable(object sender, EventArgs e)
      {
          CheckGroupReady();
      }
  
      private void GroupTimer_Elapsed(object sender, ElapsedEventArgs e)
      {
          GroupTimer.Stop();
          StopFiles();
          CheckFiles();
          CheckGroupReady();
          if (!IsGroupReady &amp;&amp; GroupFailed != null)
              GroupFailed(this, new EventArgs());
      }
  
      public void Dispose()
      {
          this.StopFiles();
          this.Files.Clear();
      }
  }
  </code></pre>
  
  <p>WatchedFile is the following:</p>
  
  <pre><code>public class WatchedFile
  {
      private static readonly ILog logger = LogManager.GetLogger(typeof(WatchedFile));
      public WatcherFile File { get; private set; }
      public bool IsFileAvailable { get; private set; }
      public event EventHandler FileAvailable;
      private FileSystemWatcher Watcher { get; set; }
      public string DirectoryPath { get; private set; }
      public string FilePath { get; private set; }
      public WatchedFile(WatcherFile file, string directoryPath)
      {
          this.File = file;
          this.DirectoryPath = directoryPath;
          CheckForFile();
          if (IsFileAvailable)
              return;
          try
          {
              Watcher = new FileSystemWatcher(directoryPath);
              Watcher.Filter = File.FileMatchPattern;
              Watcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.LastAccess | NotifyFilters.DirectoryName;
              Watcher.Created += Watcher_Created;
              Watcher.EnableRaisingEvents = true;
          }
          catch(Exception ex)
          {
              logger.Error("WatchedFile FileSystemWatcher", ex);
              throw;
          }
  
      }
      public void Stop()
      {
          if(Watcher != null)
              Watcher.EnableRaisingEvents = false;
      }
      private void Watcher_Created(object sender, FileSystemEventArgs e)
      {
          this.FilePath = e.FullPath;
          MarkFileAvailable();
      }
      private readonly object sync = new object();
      private void MarkFileAvailable()
      {
          lock(sync)
          {
              if(!this.IsFileAvailable)
              {
                  this.IsFileAvailable = true;
                  if (FileAvailable != null)
                      FileAvailable(this, new EventArgs());
              }
          }
      }
      public bool CheckForFile()
      {
          try
          {
              var files = Directory.GetFiles(this.DirectoryPath, this.File.FileMatchPattern, SearchOption.TopDirectoryOnly);
              if (files.Length &gt; 0)
              {
                  this.FilePath = files.First();
                  MarkFileAvailable();
              }
              return this.IsFileAvailable;
          }
          catch(Exception ex)
          {
              logger.Error("CheckForFile", ex);
              throw;
          }
      }
  }
  </code></pre>
  
  <p>The purpose of this code is to allow an end user to drop a folder on a network share which is supposed to contain a set of files, defined by a pattern (FileName*.csv as an example) and if all the files are present within in a set amount of time it triggers an event that downstream systems pickup, if not it triggers a failure event.</p>