Пример #1
0
        public void StartSync()
        {
            Exception searchError = null;

            try
            {
                lock (ChildDirectorySearchers)
                {
                    ChildDirectorySearchers = new List <AsyncFileFinder>();
                }
                Debug.Print("StartSync Called, Searching in " + _SearchDirectory + " For Mask " + _SearchMask);
                String         sSearch     = Path.Combine(_SearchDirectory, "*");
                Queue <String> directories = new Queue <string>();
                //Task:
                //First, Search our folder for matching files and add them to the queue of results.
                Debug.Print("Searching for files in folder");
                NativeMethods.WIN32_FIND_DATA findData;
                IntPtr fHandle = NativeMethods.FindFirstFile(sSearch, out findData);
                while (fHandle != IntPtr.Zero)
                {
                    if (_Cancelled)
                    {
                        FireAsyncFileFindComplete(AsyncFileFindCompleteEventArgs.CompletionCauseEnum.CompleteCancelled);
                        return;
                    }
                    //if the result is a Directory, add it to the list of result directories if it passes the recursion test.
                    if ((findData.dwFileAttributes & FileAttributes.Directory) == FileAttributes.Directory)
                    {
                        if (findData.Filename != "." && findData.Filename != "..")
                        {
                            if (
                                DirectoryRecursionFilter(new FileSearchResult(findData,
                                                                              Path.Combine(sSearch, findData.Filename))))
                            {
                                Debug.Print("Found Directory:" + findData.Filename + " Adding to Directory Queue.");
                                directories.Enqueue(findData.Filename);
                            }
                        }
                    }
                    else if (findData.Filename.Length > 0)
                    {
                        //make sure it matches the given mask.
                        if (FitsMask(findData.Filename, _SearchMask))
                        {
                            FileSearchResult fsr = new FileSearchResult(findData,
                                                                        Path.Combine(_SearchDirectory, findData.Filename));
                            if (FileFilter(fsr) && !_Cancelled)
                            {
                                Debug.Print("Found File " + fsr.FullPath + " Raising Found event.");
                                FireAsyncFileFound(new AsyncFileFoundEventArgs(fsr));
                            }
                        }
                    }
                    findData = new NativeMethods.WIN32_FIND_DATA();
                    if (!NativeMethods.FindNextFile(fHandle, out findData))
                    {
                        Debug.Print("FindNextFile returned False, closing handle...");
                        NativeMethods.FindClose(fHandle);
                        fHandle = IntPtr.Zero;
                    }
                }


                //find all directories in the search folder which also satisfy the Recursion test.
                //Construct a new AsyncFileFinder to search within that folder with the same Mask and delegates for each one.
                //Allow MaxChildren to run at once. When a running filefinder raises it's complete event, remove it from the List, and start up one of the ones that have not been run.
                //if isChild is true, we won't actually multithread this task at all.

                Debug.Print("File Search completed. Starting search of " + directories.Count +
                            " directories found in folder " + _SearchDirectory);
                while (directories.Count > 0 || ChildDirectorySearchers.Count > 0)
                {
                    if (_Cancelled)
                    {
                        break;
                    }
                    while (ChildDirectorySearchers.Count >= MaxChildren)
                    {
                        Thread.Sleep(5);
                    }
                    //add enough AsyncFileFinders to the ChildDirectorySearchers bag to hit the MaxChildren limit.

                    if (directories.Count == 0)
                    {
                        Debug.Print("No directories left. Waiting for Child Search instances to complete.");
                        Thread.Sleep(5);
                        continue;
                    }
                    Debug.Print("There are " + ChildDirectorySearchers.Count + " Searchers active. Starting more.");
                    String startchilddir = directories.Dequeue();
                    startchilddir = Path.Combine(_SearchDirectory, startchilddir);
                    AsyncFileFinder ChildSearcher = new AsyncFileFinder(startchilddir, _SearchMask, FileFilter,
                                                                        DirectoryRecursionFilter, true);
                    ChildSearcher.AsyncFileFound += (senderchild, foundevent) =>
                    {
                        AsyncFileFinder source = senderchild as AsyncFileFinder;

                        if (!_Cancelled)
                        {
                            FireAsyncFileFound(foundevent);
                        }
                    };
                    ChildSearcher.AsyncFileFindComplete += (ob, ev) =>
                    {
                        AsyncFileFinder ChildSearch = (AsyncFileFinder)ob;
                        lock (ChildDirectorySearchers)
                        {
                            Debug.Print("Child Searcher " + ChildSearch.SearchDirectory +
                                        " issued a completion event, removing from list.");
                            ChildDirectorySearchers.Remove(ChildSearch);
                        }
                    };

                    lock (ChildDirectorySearchers)
                    {
                        ChildDirectorySearchers.Add(ChildSearcher);
                    }

                    if (!isChild)
                    {
                        Debug.Print("Starting sub-search asynchronously");
                        ChildSearcher.Start();
                    }
                    else
                    {
                        Debug.Print("Starting sub-search synchronously");
                        ChildSearcher.StartSync();
                    }
                }
                Debug.Print("Exited Main Search Loop: Queue:" + directories.Count + " Child Searchers:" +
                            ChildDirectorySearchers.Count);
            }
            catch (Exception exx)
            {
                searchError = exx;
            }

            _IsSearching = false;
            if (searchError != null)
            {
                FireAsyncSearchError(searchError);
            }
            var completecause = _Cancelled
                ? AsyncFileFindCompleteEventArgs.CompletionCauseEnum.CompleteCancelled
                : AsyncFileFindCompleteEventArgs.CompletionCauseEnum.CompleteSuccess;

            if (searchError != null)
            {
                completecause = AsyncFileFindCompleteEventArgs.CompletionCauseEnum.CompleteError;
            }
            FireAsyncFileFindComplete
                (completecause);
        }
Пример #2
0
 public FileSearchResult(NativeMethods.WIN32_FIND_DATA pFindData, String pFullPath)
 {
     _FindData = pFindData;
     _FullPath = pFullPath;
 }