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\
中创建了副本

有代码:

命名空间观察者 公共类观察者 结构路径 公共字符串源路径; 公共列表&ltstring&gt目的地; 公共 FileSystemWatcher 观察者; 列表&ltPaths&gt路径=新列表&ltPaths&gt(); 公共观察者() 创建WatchTower(); 公共无效手表() foreach(路径中的路径 p) p.Watcher.Created += (sender, e) => onCreate(sender, e, p.destinations); 无效的 createWatchTower() 路径 p1; p1.destinations = 新列表&ltstring&gt(); 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 = 新列表&ltstring&gt(); 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&ltstring&gt 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# FileSystemWatcher - 多个事件

c# 中的FileSystemWatcher问题

C#(098):文件监视 FileSystemWatcher

C#的FileSystemWatcher用法实例详解

C# 之 FileSystemWatcher事件多次触发的解决方法

C# 中的 FileStream 和 FileSystemWatcher,奇怪的问题“进程无法访问文件”