i made a program that search logical drives to find a specific file .if user type file name an click search button , searching begins , but i don't know how to stop searching in the middle of process.can you help me ?
You need to run the search in a background thread (Using BackgroundWorker is the most convenient way to do this) then you can still handle input to cancel it.
When you are handling the cancel request you may need to use Thread.Abort on the executing thread or BackgroundWorker.CancelAsync() on the BackgroundWorker.
Alternatively you can have the executing thread check a variable while in the processing loop or at the start of a recursive function - to cancel you simple need to set this variable when handling the cancel request.
You should perform the search on a background thread so that it doesn't block the UI. This article has a good introduction and walkthrough of the changes that you'll need to make to your app.
You need to use Backgroundworker class in .net. It executes on separate thread and it has inbuilt methods/properties for cancellation, report progress and lot more...
Have a look at following article to get started with it:
http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx
As others have mentioned, your solution may be to use BackgroundWorker
with CancelAsync
method.
Here is some working code which you could use with minor modifications:
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();
}
}