public static SearchResponse PerformSearch(SearchRequest request) { Regex FromWildcard(string pattern) { return(new Regex("^" + Regex.Escape(pattern) .Replace("\\*", ".*") .Replace("\\?", ".") + "$", RegexOptions.IgnoreCase)); } var response = new SearchResponse(); var inputFiles = new BlockingCollection <FileInfo>(); var includeFilePatterns = request.IncludeFileWildcards.Distinct().Select(FromWildcard).ToList(); var excludeFileWildcards = request.ExcludeFileWildcards.ToList(); if (request.ExcludeBinaryFiles) { excludeFileWildcards.AddRange(BinaryFiles); } var excludeFilePatterns = excludeFileWildcards.Distinct().Select(FromWildcard).ToList(); // File list task Task.Run(() => { try { // Get some input foreach (var file in EnumerateFiles(request, request.Directory, "*", request.DirectoryOption) .Select(f => new FileInfo(f)) .Where(fi => ToBeSearched(request, fi, includeFilePatterns, excludeFilePatterns))) { if (request.Aborted) { break; } else { inputFiles.Add(file); } } } catch (Exception ex) { response.SetError(new ApplicationException("Failed to enumerate files", ex)); } finally { // No more input inputFiles.CompleteAdding(); } }); // File contents search tasks Task.WhenAll(Enumerable.Range(0, Math.Max(request.ParallelSearches, 1)) .Select((i) => CreateSearchTask(request, inputFiles, response))) .ContinueWith((task) => { // Output finished response.Results.CompleteAdding(); }); // Return response immediately return(response); }
public abstract SearchResult PerformSearch(SearchRequest request, FileInfo file);