Sunday, January 07, 2007

FileCreationWatcher

A few weeks ago, I received an e-mail from someone who asked me if I could give more details about a class I created at work, that is essentially a wrapper around the FileSystemWatcher class, and that detects the creation of files more reliably. You can read a discussion about this on Channel 9, in this thread. I sent him an e-mail back, with a simplified version of the wrapper class, and because I think this could also be useful for other people, I decided to post it here.

public class FileCreationWatcher : IDisposable
{
  FileSystemWatcher fWatcher;

  public FileCreationWatcher(string path, string filter)
  {
    Initialize(path, filter);
  }

  void Initialize(string path, string filter)
  {
    fWatcher = new FileSystemWatcher(path, filter);
    fWatcher.Created += OnFileCreated;
    fWatcher.Error += OnError;
  }

  void OnFileCreated(object sender, FileSystemEventArgs e)
  {
    FileInfo lFile = new FileInfo(e.FullPath);
    if (lFile.Exists)
    {
      // schedule the processing on a different thread
      ThreadPool.QueueUserWorkItem(delegate
      {
        while(true)
        {
          // wait 100 milliseconds between attempts to read
          Thread.Sleep(TimeSpan.FromMilliseconds(100));
          try
          {
            // try to open the file
            lFile.OpenRead().Close();
            break;
          }
          catch(IOException)
          {
            // if the file is still locked, keep trying
            continue;
          }
        }

        // the file can be opened successfully: raise the event
        if (Created != null)
          Created(this, e);
      });
    }
  }

  void OnError(object sender, ErrorEventArgs e)
  {
    // when an error occurs, the current FileSystemWatcher is disposed,
    // and a new one is created
    string lPath = fWatcher.Path;
    string lFilter = fWatcher.Filter;
    fWatcher.Dispose();
    Initialize(lPath, lFilter);
  }

  public void Start() { fWatcher.EnableRaisingEvents = true; }

  public void Stop() { fWatcher.EnableRaisingEvents = false; }

  public event FileSystemEventHandler Created;

  #region IDisposable Members

  public void Dispose() { Dispose(true); GC.SuppressFinalize(this); }

  ~FileCreationWatcher() { Dispose(false); }

  protected virtual void Dispose(bool disposing)
  {
    if (disposing)
      fWatcher.Dispose();
  }

  #endregion
}
Technorati tags: , .
Comments:
Hi Tommy

Are you aware of a way to implement this class on Windows Mobile 5?
 
OpenNETCF has an implementation of FileSystemWatcher for the Compact Framework.
 
Post a Comment

Links to this post:

Create a Link