【问题标题】:Why is enumerate files returning the same file more than once?为什么枚举文件多次返回同一个文件?
【发布时间】:2012-05-23 07:27:43
【问题描述】:

我有这个代码(感谢迄今为止一直在帮助的人)

它在目录和所有子目录中搜索文件名。

Files.Clear(); //BindingList<FileInfo> Datasource for a datagridview

Task.Factory.StartNew( () =>
    {
       DirectoryInfo dir = new DirectoryInfo(MainFolder);

       foreach(var file in dir.EnumerateFiles("*" + textBox1.Text + "*.doc?", SearchOption.AllDirectories).Take(200))
       {
          this.BeginInvoke( new Action(() =>
             {
                Files.Add(file);
             }));
       }
     });

问题是如果我将 textBox1.text 设置为我知道只有 1 个的东西,它会将其添加到 Files 4 次。我尝试中断指向它以确保它不是我显示它的方式。

我比较了这 4 个对象,它们是相同的。当我稍微打开搜索条件并获得 5 个结果时,其中一些是 1,一些是两倍,一些是三倍。所以有 5 个独特的结果,但总共大约有 10-12 个。

我做错了什么?

【问题讨论】:

    标签: c# winforms io .net


    【解决方案1】:

    这应该会更快并且更清晰。

    var searchPattern = "*" + textBox1.Text + "*.doc?";
    Files.Clear(); //BindingList<FileInfo> Datasource for a datagridview
    DirectoryInfo dir = new DirectoryInfo(MainFolder);
    Files.AddRange(dir.EnumerateFiles(searchPatten, SearchOption.AllDirectories).ToList());
    

    你为什么一开始使用所有的异步操作??

    【讨论】:

    • 因为它在搜索时冻结了程序。这需要 10 秒左右。
    【解决方案2】:

    你是直接使用枚举变量

    如果将变量复制到局部变量中,应该没问题

    Files.Clear(); //datagridview的BindingList数据源

        Task.Factory.StartNew( () =>
        {
            DirectoryInfo dir = new DirectoryInfo(MainFolder);
            foreach(var file in dir.EnumerateFiles("*"+textBox1.Text+"*.doc?",SearchOption.AllDirectories).Take(200))
            {
                var currentFile = file;
                this.BeginInvoke( new Action(() =>
                {
                    Files.Add(currentFile);
                }));
            }
        });
    

    【讨论】:

    • 听起来不错,但 file.Clone() 不是一个选项。我将文件变量用作 FileInfo,所以我不能将它转换为字符串。
    【解决方案3】:

    使用调用。

    您的 lambda 正在捕获正在变异的变量文件。您不仅会得到重复文件,还会丢失文件。

    【讨论】:

    • 你能再清楚一点吗,上面的大部分代码我都没有写,当我在玩它时,它更有意义,你能告诉我文件变量在哪里正在变异,因为我以为我在使用调用。
    • BeginInvoke 与您的文件枚举代码同时调用您的 lambda。一旦下一个循环迭代开始,变量文件就包含下一个文件。但是你的 lambda 期望旧的。另一种解决方案是先将文件复制到局部变量中。
    • 我将 BeginInvoke 更改为 Invoke,它似乎已经解决了。我将不得不研究他们的差异
    • Invoke 仅在您的代码完全运行后返回。这样,以后变量文件是否发生突变都没关系。我们需要防止它同时发生变异(不可预测地)。
    猜你喜欢
    • 1970-01-01
    • 2016-03-10
    • 2012-05-17
    • 2016-08-20
    • 2012-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多