C#:FileSystemWatcher-多个监视文件夹问题

Bob*_* T. 0 c# filesystemwatcher

我正在尝试用c#编写程序,正在监视多个文件夹。如果在任何监视的文件夹中添加了文件,则程序应在定义的路径中创建副本。我的问题是当我创建文件时,程序会在错误的文件夹中创建副本

例如,如果我将文件添加到

 C:\ folder1 \ stuff \ 
它应该在创建副本
 D:\ stuff1 \ copied1 ... 3 \
但是它创建了副本
 D:\ stuff2 \ copyed1 ... 3 \

有代码:

命名空间观察者
{
    公共班级观察者
    {

        结构路径
        {
            公共字符串sourcePath;
            公共List <string>目的地;
            公共FileSystemWatcher Watcher;
        }

        List <Paths>路径=新的List <Paths>();

        公众观察者()
        {
            createWatchTower();
        }

        公共无效值watch()
        {
            foreach(路径中的路径p)
            {
                p.Watcher.Created + =(sender,e)=> onCreate(sender,e,p.destinations);
            }
        }

        无效createWatchTower()
        {
            路径p1;
            p1.destinations =新的List <string>();

            p1.sourcePath = @“ C:\ folder1 \ stuff \”;

            p1.Watcher = new FileSystemWatcher();
            p1.Watcher.Path = p1.sourcePath;
            p1.Watcher.EnableRaisingEvents = true;

            p1.destinations.Add(@“ D:\ stuff1 \ copied1 \”);
            p1.destinations.Add(@“ D:\ stuff1 \ copied2 \”);
            p1.destinations.Add(@“ D:\ stuff1 \ copied3 \”);
            path.Add(p1);


            路径p2;
            p2.destinations =新的List <string>();
            p2.sourcePath = @“ C:\ folder2 \ stuff2”;

            p2.Watcher = new FileSystemWatcher();
            p2.Watcher.Path = p2.sourcePath;
            p2.Watcher.EnableRaisingEvents = true;

            p2.destinations.Add(@“ D:\ stuff2 \ copied1 \”);
            p2.destinations.Add(@“ D:\ stuff2 \ copied2 \”);
            p2.destinations.Add(@“ D:\ stuff2 \ copied3 \”);

            path.Add(p2);

        }

        私有无效onCreate(对象o,FileSystemEventArgs e,List <string> dest)
        {

            foreach(dst中的字符串s)
            {
                尝试
                {
                    System.IO.File.Copy(e.FullPath,s + e.Name,true);
                }
                抓住(前例外)
                {
                    Console.WriteLine(ex);
                }
            }
        }
    }
}

有人可以帮我吗?我认为这是因为foreach中的事件,但是我找不到解决方案。非常感谢

Dir*_*irk 5

如果您未使用C#5,则问题在于方法p中的foreach循环中的闭包为watch

foreach (Paths p in paths)
{
    p.Watcher.Created += (sender, e) => onCreate(sender, e, p.destinations);
}
Run Code Online (Sandbox Code Playgroud)

plambda内部使用时,它将捕获变量,而不是其值。因此,如果Created引发该事件,p则将引用paths列表的最后一项。

您可以通过在foreach循环中引入一个临时变量来避免这种情况:

foreach (Paths p in paths)
{
    var tmp = p;
    p.Watcher.Created += (sender, e) => onCreate(sender, e, tmp.destinations);
}
Run Code Online (Sandbox Code Playgroud)

您可以在这个Stackoverflow问题中找到有关C#5中发生的变化的更详细的分析。