【问题标题】:speeding up windows file search with C#使用 C# 加速 Windows 文件搜索
【发布时间】:2009-11-15 19:00:20
【问题描述】:

我制作了一个搜索逻辑驱动器以查找特定文件的程序。如果用户键入文件名 单击搜索按钮,搜索开始,但我不知道如何在过程中停止搜索。您能帮帮我吗?

【问题讨论】:

    标签: c# .net windows search


    【解决方案1】:

    您应该在后台线程上执行搜索,以免它阻塞 UI。 This article 对您需要对应用进行的更改进行了很好的介绍和演练。

    【讨论】:

      【解决方案2】:

      您需要在 .net 中使用 Backgroundworker 类。它在单独的线程上执行,并具有用于取消、报告进度等的内置方法/属性...

      请查看以下文章以开始使用它:

      http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx

      【讨论】:

        【解决方案3】:

        您需要在后台线程中运行搜索(使用 BackgroundWorker 是最方便的方法)然后您仍然可以处理输入以取消它。

        当您处理取消请求时,您可能需要在执行线程上使用 Thread.Abort 或在 BackgroundWorker 上使用 BackgroundWorker.CancelAsync()。

        或者,您可以让执行线程在处理循环或递归函数开始时检查变量 - 要取消,您只需在处理取消请求时设置此变量。

        【讨论】:

          【解决方案4】:

          正如其他人所提到的,您的解决方案可能是使用 BackgroundWorkerCancelAsync 方法。

          这里有一些工作代码,您只需稍作修改即可使用:

          class Program
          {
              static void Main(string[] args)
              {
                  var search = new FileSearcher().FindFile(@"d:\users", "autofac.dll", f => Console.WriteLine(f.FullName), () => Console.WriteLine("Finished"));
          
                  Console.WriteLine("C - cancel, else - finish");
          
                  for (; ; )
                  {
                      var command = Console.ReadLine();
                      switch (command)
                      {
                          case "C":
                              search.Cancel();
                              break;
          
                          default:
                              return;
                      }
                  }
              }
          }
          
          public class FileSearcher
          {
              public FileSearch FindFile(string searchPath, string fileName, Action<FileInfo> onFileFound, Action onSearchFinished)
              {
                  var search = new FileSearch(new DirectoryInfo(searchPath), fileName);
                  search.FileFound += onFileFound;
                  search.Finished += onSearchFinished;
                  search.Run();
                  return search;
              }
          }
          
          public class FileSearch
          {
              readonly BackgroundWorker _worker = new BackgroundWorker();
              readonly DirectoryInfo _searchPath;
              readonly string _template;
          
              public FileSearch(DirectoryInfo searchPath, string template)
              {
                  _searchPath = searchPath;
                  _template = template;
          
                  _worker.DoWork += _worker_DoWork;
                  _worker.RunWorkerCompleted += _worker_RunWorkerCompleted;
                  _worker.WorkerSupportsCancellation = true;
              }
          
              void _worker_DoWork(object sender, DoWorkEventArgs e)
              {
                  foreach (var directory in GetPartiallyFlatDirectories(_searchPath, 4))
                  {
                      if (_worker.CancellationPending)
                          break;
          
                      foreach (var file in directory.GetFiles(_template, SearchOption.AllDirectories))
                          FileFound.Raise(file);
                  }
              }
          
              static IEnumerable<DirectoryInfo> GetPartiallyFlatDirectories(DirectoryInfo directory, int flatDepth)
              {
                  if (flatDepth == 0)
                  {
                      yield return directory;
                      yield break;
                  }
          
                  foreach (var subDir in directory.GetDirectories())
                  {
                      var flattened = GetPartiallyFlatDirectories(subDir, flatDepth - 1);
          
                      if (!flattened.Any())
                          yield return subDir;
                      else
                          foreach (var flatDirectory in flattened)
                              yield return flatDirectory;
                  }
              }
          
              void _worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
              {
                  Finished.Raise();
              }
          
              public void Cancel()
              {
                  _worker.CancelAsync();
              }
          
              public event Action<FileInfo> FileFound;
              public event Action Finished;
          
              public void Run()
              {
                  _worker.RunWorkerAsync();
              }
          }
          
          public static class DelegateExtensions
          {
              public static void Raise<T>(this Action<T> action, T obj)
              {
                  if (action != null)
                      action(obj);
              }
          
              public static void Raise(this Action action)
              {
                  if (action != null)
                      action();
              }
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2012-12-04
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-09-26
            相关资源
            最近更新 更多