I am trying to programatically create and dispose of file system watchers, but I am running into an issue when trying to dispose of them.

When I try to use the code:

            // dispose of any existing watchers.
            foreach (FileSystemWatcher fileWatcher in this.Controls)
            {
                fileWatcher.Dispose();
            }

I am receiving a System.InvalidCastException exception.

The details show:

> {"Unable to cast object of type 'System.Windows.Forms.Button' to type 'System.IO.FileSystemWatcher'."}

Which is obviously true, but I thought with the qualifier of FileSystemWatcher this would work by skipping over any controls that are not System.IO.FileSystemWatcher. Evidently not.

Any suggestions?

PS for the admins - When posting this I was receiving this error as well:

The code snippet in your post is formatted incorrectly. Please use the Code button in the editor toolbar when posting whitespace-sensitive text or curly braces.

My code snippet was inserted using the Code button...odd...

How are you creating your FileSystemWatchers? Am pretty sure they aren't inserted into the Controls array. Wouldn't it be easier to keep track of them in a separate list?

First

but I thought with the qualifier of FileSystemWatcher

FileSystemWatcher is a type, not a qualifier. When you use foreach loop, your loop variable's type has to match with the collection item's type. So when you loop this.Controls collection you're dealing with a type Control.

Here's a sample how to loop all controls of the type 'Button' in your form:

    foreach (Control oneControl in this.Controls)
    {
         if (oneControl.GetType() == typeof(Button))
         {
            // It's a button
         }
    }

Objects of the type FileSystemWatcher are not controls and you won't find them in the form's Controls collection. Since you create FileSystemWatcher objects in your code you can save them in a way you can access them later.

The easiest solution that came in to my mind is to use a List collection. Here's the code with comments:

    // This list holds a reference to all watchers that are created
    private List<FileSystemWatcher> listOfFileSystemWatchers = new List<FileSystemWatcher>();

    // Event handler which is called when a change occurs
    private void myWatcher_Changed(object sender, FileSystemEventArgs e)
    {
        // Here we do something
        MessageBox.Show(e.FullPath + " changed");
    }

    // I used a button to create new FileSystemWatchers. You may use some other way
    private void button3_Click(object sender, EventArgs e)
    {
        FileSystemWatcher newFSysWatcher;

        // Create a very basic FileSystemWatcher object
        newFSysWatcher = new FileSystemWatcher(@"D:\Temp", @"*.txt");
        newFSysWatcher.EnableRaisingEvents = true;
        newFSysWatcher.Changed += new FileSystemEventHandler(myWatcher_Changed);

        // Add watcher to the list to access it later
        listOfFileSystemWatchers.Add(newFSysWatcher);
    }

    // Second button calls Dispose methods for each FileSystemWatcher object
    private void button4_Click(object sender, EventArgs e)
    {
        foreach (FileSystemWatcher fsw in listOfFileSystemWatchers)
        {
            fsw.Dispose();
        }
    }

HTH

Edited 1 Year Ago by Teme64: Fixed typos and formatting

Comments
Thanks!

I like the idea of the list!

I haven't been writing code for a while and I have a new project to work on and completely forgot about such a basic concept. Wow.

Thanks!

This question has already been answered. Start a new discussion instead.