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中的事件,但是我找不到解决方案。非常感谢
如果您未使用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中发生的变化的更详细的分析。