我制作了一个搜索逻辑驱动器以查找特定文件的程序。如果用户键入文件名单击搜索按钮,搜索开始,但我不知道如何在过程中停止搜索。你能帮我吗?
问问题
1397 次
4 回答
4
您应该在后台线程上执行搜索,这样它就不会阻塞 UI。本文对您需要对应用程序进行的更改进行了很好的介绍和演练。
于 2009-11-15T19:04:57.747 回答
1
您需要在后台线程中运行搜索(使用 BackgroundWorker 是最方便的方法)然后您仍然可以处理输入以取消它。
在处理取消请求时,您可能需要在执行线程上使用 Thread.Abort 或在 BackgroundWorker 上使用 BackgroundWorker.CancelAsync()。
或者,您可以让执行线程在处理循环中或递归函数开始时检查变量 - 要取消,您只需在处理取消请求时设置此变量。
于 2009-11-15T19:04:11.807 回答
1
您需要在 .net 中使用 Backgroundworker 类。它在单独的线程上执行,并具有用于取消、报告进度等的内置方法/属性……
请查看以下文章以开始使用它:
http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx
于 2009-11-15T19:11:29.460 回答
0
正如其他人所提到的,您的解决方案可能是使用BackgroundWorker
withCancelAsync
方法。
以下是一些工作代码,您只需稍作修改即可使用:
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();
}
}
于 2009-11-15T20:17:49.337 回答