【问题标题】:C# : FileSystemWatcher - multiple watching folders issueC#:FileSystemWatcher - 多个监视文件夹问题
【发布时间】: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 未初始化。请发布您的实际代码。

标签: c# filesystemwatcher


【解决方案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 Stackoverflow question 中找到有关 C# 5 中更改内容的更详细分析。

    【讨论】:

    • 它有效!!!! :) 非常感谢 ! :) 我知道 foreach 循环中会有问题,但我不知道如何解决它! :) 非常感谢 ! :)
    【解决方案3】:

    您可以将路径创建为Dictionary (sourcePath => p) 而不是List,并在onCreate 方法中通过调用获取目标

    var dest = paths[((FileSystemWatcher)sender).Path].destinations
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-18
      • 1970-01-01
      • 1970-01-01
      • 2023-03-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多