有没有办法停止Directory.GetFiles搜索

时间:2017-10-22 15:26:16

标签: c# directory getfiles

我使用Directory.GetFiles()搜索多文件夹目录中的文件,其中一些文件夹太大,因此搜索最多可能需要60秒。在下面的代码中,搜索在用户停止输入后开始一秒钟,当用户键入文件名并且在键入文件名时不暂停但是如果他/她在单词的中间暂停搜索将开始并且将即使他/她再次开始打字,也不会停止,直到它完成。

我想要做的是在用户输入时停止搜索,可能在inputFileName_TextChanged方法中。

使用Directory.GetFiles时,有没有办法停止已经启动的搜索?

using System.Timers;
using System.IO;

namespace findFileTest
{

    public partial class MainWindow : Window
    {
        Timer timer = new Timer();

        public MainWindow()
        {
            InitializeComponent();

            timer.Elapsed += new ElapsedEventHandler(TimerEvent);
            timer.Interval = 1000;
            timer.Enabled = true;
            timer.Stop();
        }

        private void inputFileName_TextChanged(object sender, TextChangedEventArgs e)
        {
            // How to stop the search currently in process here
            timer.Stop();
            timer.Start();
        }

        public void TimerEvent(object source, ElapsedEventArgs e)
        {
            timer.Stop();
            findFile();
        }

        private void findFile()
        {
            string fName = "";

            this.Dispatcher.Invoke(() => {
                fName = inputFileName.Text;
            });

            var fType = ".txt";
            var fileName = fName.Trim() + fType;

            var file = Directory.GetFiles(@"C:\TestFolder\", fileName, SearchOption.AllDirectories).FirstOrDefault();
            if (file == null) {
                Console.WriteLine("File not found");
            }
            else {
                Console.WriteLine("Found:" + file);
            }
        }
    }
}

1 个答案:

答案 0 :(得分:2)

  

有没有办法停止使用Directory.GetFiles时已经启动的搜索?

不,不安全。 GetFiles()方法在返回之前不提供任何中断其工作的机制。你必须中止线程,这会导致许多其他问题。

正如this comment中所述,从字面上理解您的请求的答案是使用Directory.EnumerateFiles()方法。此方法通过提供一次返回一个文件的枚举器来表示底层FindFirstFile()FindNextFile()的语义。每次返回一个新文件时,您都有机会中断枚举并返回而不做更多工作。

请注意,即使使用EnumerateFiles(),在找到与搜索模式匹配的内容之前,您也不会获得第一个文件结果。如果您切换到使用EnumerateFiles(),您可能还希望在输入上进行自己的匹配,而不是让EnumerateFiles()这样做。即传递"*"作为搜索字符串。这会使整个操作减慢一点,但您将有机会中断搜索目录和子目录中每个文件的操作,而不是仅在找到匹配文件时。

最后,我建议根据您明显的用例,您可能想要重新考虑使用Directory类。根据您发布的代码,每次用户输入一些新文本时,您都会开始搜索文件系统,这是一个必然很慢的操作。恕我直言,最好建立一次索引(例如,Dictionary<string, List<string>>将没有扩展名的文件名 - 即Path.GetFileNameWithoutExtension() - 映射到目录中每个匹配文件的完整路径)。这样,您就不必中断任何事情。用户输入文本后的“搜索”部分几乎是即时的。

在完全索引目录之前,当然会有一个初始延迟。这取决于你如何处理它。但我建议提供一种机制,既向用户指示索引不完整,又检查你拥有的内容,以防用户查找的文件与已编入索引的文件匹配。

请注意,使用的常用Windows文件系统(FAT,FAT32,NTFS等)不区分大小写,因此您需要使用StringComparer.OrdinalIgnoreCase初始化字典。 “Ordinal”,因为文件系统名称需要匹配用户键入的确切字符,并“忽略大小写”,以便搜索不区分大小写。

我想在你的场景中,当用户使用你的程序搜索文件时,不太可能添加或删除文件。但是如果您担心这种情况,您可以向用户提供“刷新”按钮以强制重新编制索引,或者如果添加或删除文件,则使用FileSystemWatcher自动更新索引。