Hello,
I'm not sure if you are running into the same issue I had a while back or
not, but just incase here are my thoughts.
I remember I would get the same error and the only way I could get around it
was by calling dispose on the FileSystemWatcher. Here are my notes from the
code I wrote a while back
/// Release handles to directory. A directory cannot be fully
/// deleted until it is released. Need to use Dispose because
/// can't wait for garbage collector.
It worked for me. So I my architectured was a class called
FileSystemMoniter (which I created) and in this class I setup the
FileSystemWatcher and exposed the events of FileSystemWatcher. Mine might
be a bit different in that for each FileSystemWatcher event I had them raise
a my own Changed event so that my subscribers only had to listen to one
event when any changes occured.
Then when I needed to start and stop watching I released the references to
the changed event and called dispose on the FileSystemMonitor. Here is some
of the code.
/// <summary>
/// Monitors the file system for any changes in the specified path.
/// </summary>
public class FileSystemMonitor : IDisposable {
# region ***** FIELDS *****
private int _ignoreChangesPeriod;
private int _lastChangeTime;
private FileSystemWatcher _watcher;
private FileSystemWatcher _watcherChanged;
private string _watchPath;
public delegate void FileSystemChangedHandler(object sender,
FileSystemEventArgs e);
public event FileSystemChangedHandler Changed;
# endregion
# region ***** CONSTRUCTORS *****
public FileSystemMonitor(string path) {
_watchPath = path;
_watcher = new FileSystemWatcher();
_watcher.Created += new FileSystemEventHandler(OnFileCreated);
_watcher.Deleted += new FileSystemEventHandler(OnFileDeleted);
_watcher.Renamed += new RenamedEventHandler(OnFileRenamed); // NOTE: THIS
MAY NOT BE WORKING.
SetWatcherProperties(_watcher);
// Setup second watcher to watch changed because
// Create, Delete, and rename don't seem to fire when NotifyFilter is set.
// NOTE: THIS MAY NOT BE WORKING.
_watcherChanged = new FileSystemWatcher();
_watcherChanged.Changed += new FileSystemEventHandler(OnFileChanged);
_watcherChanged.NotifyFilter = NotifyFilters.FileName |
NotifyFilters.DirectoryName;
SetWatcherProperties(_watcherChanged);
}
# endregion
# region ***** PUBLIC METHODS *****
/// <summary>
/// Release handles to directory. A directory cannot be fully
/// deleted until it is released. Need to use Dispose because
/// can't wait for garbage collector.
/// </summary>
public void Dispose() {
_watcher.Dispose();
_watcherChanged.Dispose();
}
# endregion
# region ***** PRIVATE METHODS *****
private void SetWatcherProperties(FileSystemWatcher watcher) {
watcher.Path = _watchPath;
watcher.Filter = "*.*";
watcher.IncludeSubdirectories = true;
watcher.EnableRaisingEvents = true;
}
private void OnFileCreated(object sender, FileSystemEventArgs e) {
Debug.WriteLine("FileSystmeMonitor.OnFileCreated: " + e.FullPath);
CallChanged(sender, e);
}
private void OnFileDeleted(object sender, FileSystemEventArgs e) {
Debug.WriteLine("FileSystmeMonitor.OnFileDeleted: " + e.FullPath);
CallChanged(sender, e);
}
private void OnFileRenamed(object sender, RenamedEventArgs e) {
Debug.WriteLine("FileSystmeMonitor.OnFileRenamed: " + e.FullPath);
CallChanged(sender, e);
}
private void OnFileChanged(object sender, FileSystemEventArgs e) {
Debug.WriteLine("FileSystmeMonitor.OnFileChanged: " + e.FullPath);
CallChanged(sender, e);
}
private void CallChanged(object sender, FileSystemEventArgs e) {
// Check if should ignore change.
int currentTime = System.Environment.TickCount;
if (currentTime - _lastChangeTime > _ignoreChangesPeriod) {
if (this.Changed != null) {
this.Changed(sender, e);
}
} else {
Debug.WriteLine("CallChanged Ignored");
}
_lastChangeTime = currentTime;
}
# endregion
#region ***** PROPERTIES *****
public int IgnoreChangesMiliseconds {
get { return _ignoreChangesPeriod; }
set { _ignoreChangesPeriod = value; }
}
#endregion
}
-----
These methods were in another class that was using The FileSystemMonitor.
public void StartFileMonitor() {
Debug.WriteLine("Start File Monitor: " + this.Directory);
// Setup file system monitor. This object will alert
// this image to reload when changes occur to the file system.
if (_fileSystemMonitor == null) {
_fileSystemMonitor = new FileSystemMonitor(_dirPath);
_fileSystemMonitor.IgnoreChangesMiliseconds =
AppManager.FILE_SYSTEM_IGNORE_CHANGES_TIME;
}
if (_fileSystemChangedHandler == null) {
_fileSystemChangedHandler = new
FileSystemMonitor.FileSystemChangedHandler(FileSystemMonitor_OnFileSystemChanged);
Debug.WriteLine("FileSystemHandler Created: " + this.Directory);
}
_fileSystemMonitor.Changed += _fileSystemChangedHandler;
Debug.WriteLine("FileSystemHandler Added: " + this.Directory);
}
public void StopFileMonitor() {
Debug.WriteLine("Stoping File Monitor: " + this.Directory);
// Remove event handler;
if (_fileSystemChangedHandler != null) {
_fileSystemMonitor.Changed -= _fileSystemChangedHandler;
Debug.WriteLine("FileSystemChangedHandler Removed: " + this.Directory);
}
if (_fileSystemMonitor != null) {
_fileSystemMonitor.Dispose();
Debug.WriteLine("FileSystemMonitor Disposed");
//_fileSystemMonitor = null;
}
}
Hope that helps.
--
Tom Krueger
Smart Client DevCenter -
http://msdn.microsoft.com/smartclient/
Mobile DevCenter -
http://msdn.microsoft.com/mobility
This posting is provided "as is" with no warranties and confers no rights.