C#:FileSystemWatcher - 多个监视文件夹问题
Posted
技术标签:
【中文标题】C#:FileSystemWatcher - 多个监视文件夹问题【英文标题】:C# : FileSystemWatcher - multiple watching folders issue 【发布时间】:2014-08-31 14:38:17 【问题描述】:我正在尝试用 c# 编写程序,它正在监视多个文件夹。如果在任何被监视的文件夹中添加了文件,程序应该在定义的路径中创建副本。 我的问题是当我创建文件时,程序在错误的文件夹中创建副本
例如如果我将文件添加到
C:\folder1\stuff\它应该在
D:\stuff1\copied1...3\中创建副本 但相反,它在
D:\stuff2\copied1...3\中创建了副本
有代码:
命名空间观察者 公共类观察者 结构路径 公共字符串源路径; 公共列表<string>目的地; 公共 FileSystemWatcher 观察者; 列表<Paths>路径=新列表<Paths>(); 公共观察者() 创建WatchTower(); 公共无效手表() foreach(路径中的路径 p) p.Watcher.Created += (sender, e) => onCreate(sender, e, p.destinations); 无效的 createWatchTower() 路径 p1; p1.destinations = 新列表<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\"); 路径。添加(p1); 路径 p2; p2.destinations = 新列表<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\"); 路径。添加(p2); private void onCreate(object o, FileSystemEventArgs e, List<string> dest) foreach(目标中的字符串 s) 尝试 System.IO.File.Copy(e.FullPath, s + e.Name, true); 捕捉(例外前) Console.WriteLine(ex);有人可以帮我吗?我认为这是因为 foreach 中的事件,但我找不到解决方案。 非常感谢 发帖
【问题讨论】:
您使用哪个版本的 C#? 我相信我正在使用 .NET framework 4.0 您发布的代码无法编译,因为 p1 和 p2 未初始化。请发布您的实际代码。 【参考方案1】:我有一个类似的程序作为 Windows 服务运行。我创建了一个 XML 配置文件,其中包含要监视的所有文件夹以及与每个路径对应的目标路径。然后,我为每个文件夹创建了另一个观察线程。
为了获得正确的输出路径,您需要将其与您正在观看的文件夹配对。 因此,您可以使用配置文件,也可以使用 Dictionary 或 KeyValuePairs 列表。
【讨论】:
【参考方案2】:如果您不使用 C# 5,那么问题是 watch
方法中 foreach 循环中 p
的闭包:
foreach (Paths p in paths)
p.Watcher.Created += (sender, e) => onCreate(sender, e, p.destinations);
当在 lambda 中使用 p
时,它将捕获 变量,而不是它的值。因此,如果引发Created
事件,p
将引用paths
列表的最后一项。
你可以通过在 foreach 循环中引入一个临时变量来避免这种情况:
foreach (Paths p in paths)
var tmp = p;
p.Watcher.Created += (sender, e) => onCreate(sender, e, tmp.destinations);
您可以在this *** question 中找到有关 C# 5 中更改内容的更详细分析。
【讨论】:
它有效!!!! :) 非常感谢 ! :) 我知道 foreach 循环中会有问题,但我不知道如何解决它! :) 非常感谢 ! :)【参考方案3】:您可以将路径创建为Dictionary
(sourcePath => p) 而不是List
,并在onCreate
方法中通过调用获取目标
var dest = paths[((FileSystemWatcher)sender).Path].destinations
【讨论】:
以上是关于C#:FileSystemWatcher - 多个监视文件夹问题的主要内容,如果未能解决你的问题,请参考以下文章
C#(098):文件监视 FileSystemWatcher