views:

166

answers:

4

I'm trying to write a program that could monitor multiple folders for file creations and launch the same action but with different settings for each folder. My problem is in specifying an extra parameter for the FileSystemEventHandler. I create a new FileWatcher for each directory to monitor and add the handler for the Created-action:

foreach (String config in configs)
{
    ...
    FileWatcher.Created += new System.IO.FileSystemEventHandler(FileSystemWatcherCreated)
    ...
}

void FileSystemWatcherCreated(object sender, System.IO.FileSystemEventArgs e, MySettings mSettings)
{
    DoSomething(e.FullPath, mSettings);
}

How could I get the 'mSettings' variable passed to FileSystemWatcherCreated()?

+1  A: 

You can't ask for more information than what the FileWatcher handler provides. What you can do however is to create a small classes that have access to the configuration and also have a delegate that you can attach to the FileWatcher's Created event

class Program
{
    static void Main(string[] args)
    {
        FileSystemWatcher watcher = new FileSystemWatcher("yourpath");

        var configurations = new IConfiguration[]
                                 {
                                     new IntConfiguration(20),
                                     new StringConfiguration("Something to print")
                                 };

        foreach(var config in configurations)
            watcher.Created += config.HandleCreation;
    }

    private interface IConfiguration
    {
        void HandleCreation(object sender, FileSystemEventArgs e);
    }

    private class IntConfiguration : IConfiguration
    {
        public IntConfiguration(int aSetting)
        {
            ASetting = aSetting;
        }

        private int ASetting { get; set; }

        public void HandleCreation(object sender, FileSystemEventArgs e)
        {
            Console.WriteLine("Consume your settings: {0}", ASetting);
        }
    }

     public class StringConfiguration : IConfiguration
    {
        public string AnotherSetting { get; set;}

        public StringConfiguration(string anotherSetting)
        {
            AnotherSetting = anotherSetting;
        }

        public void HandleCreation(object sender, FileSystemEventArgs e)
        {
            Console.WriteLine("Consume your string setting: {0}", AnotherSetting);
        }
    }
}
Thomas
This exactly why you should use closures, and not write all this extra unneeded code.
leppie
A: 

You need to understand what you are using. FileSystemEventHandler's definition is-

public delegate void FileSystemEventHandler(object sender, FileSystemEventArgs e);

You can't pass the third argument. In order to pass the data 'mSettings', you might have to write your own extra code, I'm afraid.

Nayan
+1  A: 
foreach (String config in configs)
{
    ...
    FileWatcher.Created += (s,e) => DoSomething(e.FullPath, mSettings);
    ...
}
leppie
How do you unsubscribe from the event?What if the first ... expands to mSettings.MyProperty = config?
Henrik
Yes thank you! Works exactly as I wanted. I knew there had to be a simple way of achieving this.
peku
+1  A: 

foreach (String config in configs) 
{ 
    ... 
    MySettings mSettings = new MySettings(...); // create a new instance, don't modify an existing one
    var handler = new System.IO.FileSystemEventHandler( (s,e) => FileSystemWatcherCreated(s,e,msettings) );
    FileWatcher.Created += handler;
    // store handler somewhere, so you can later unsubscribe
    ... 
} 

void FileSystemWatcherCreated(object sender, System.IO.FileSystemEventArgs e, MySettings mSettings) 
{ 
    DoSomething(e.FullPath, mSettings); 
} 
Henrik
Thank you for this also, seems to be a more "complete" version of the answer I accepted but since I won't be needing to unsubscribe I think I'll stick with the simplest approach. +1
peku