private static Task CreateSearchTask(SearchRequest request, BlockingCollection <FileInfo> inputFiles, SearchResponse response) { return(Task.Run(() => { try { foreach (var file in inputFiles.GetConsumingEnumerable(request.CancellationToken)) { try { if (!file.Exists) { continue; } var results = request.Algorithm.PerformSearch(request, file); if (results.Match) { response.Results.Add(results); Interlocked.Increment(ref response.Hits); } else { Interlocked.Increment(ref response.Misses); } } catch (Exception ex) { var excuse = ""; if (ex.Message.EndsWith("used by another process.")) { excuse = "\nFile is locked."; } response.SetError(new ApplicationException($"Failed to process file: \n{file.FullName}{excuse}", ex)); response.Results.Add(SearchResult.Error); } } } catch (OperationCanceledException) { } catch (Exception ex) { response.SetError(ex); } })); }
public static SearchResponse PerformFilter(SearchRequest request, IEnumerable <string> paths) { var response = new SearchResponse(); var inputFiles = new BlockingCollection <FileInfo>(); try { foreach (var path in paths) { inputFiles.Add(new FileInfo(path)); } } 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); }
private static Task CreateSearchTask(SearchRequest request, BlockingCollection <FileInfo> inputFiles, SearchResponse response) { return(Task.Run(() => { try { foreach (var file in inputFiles.GetConsumingEnumerable(request.CancellationToken)) { try { if (!file.Exists) { continue; } var results = request.Algorithm.PerformSearch(request, file); if (results.Match) { response.Results.Add(results); Interlocked.Increment(ref response.Hits); } else { Interlocked.Increment(ref response.Misses); } } catch (Exception ex) { response.SetError(new ApplicationException("Failed to process file", ex)); } } } catch (OperationCanceledException) { } catch (Exception ex) { response.SetError(ex); } })); }
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); }