private static async Task <ConcurrentDictionary <string, FileInfo> > GetFileSystemEntriesAsync( FileInfo pathFileInfo, ConcurrentBag <Task> tasks, IProgress <FileSystemEnumerationProgress> progress, IReadOnlyList <string> directoryExclusions = null, ConcurrentDictionary <string, FileInfo> fileSystemEntries = null, bool continueOnUnauthorizedAccessExceptions = true, bool continueOnPathTooLongExceptions = true) { #region Validation if (directoryExclusions == null) { directoryExclusions = new List <string>(); } if (fileSystemEntries == null) { fileSystemEntries = new ConcurrentDictionary <string, FileInfo>(StringComparer.OrdinalIgnoreCase); } if (pathFileInfo == null) { throw new ArgumentNullException("pathFileInfo"); } #endregion try { await Task.Run(() => { try { lock (TasksCreatedCompletedLockObject) { TasksCreated++; } if ((progress != null) && (fileSystemEntries.Count > 0)) { lock (ProgressTimer) { int progressTimerTotalSeconds = (int)ProgressTimer.Elapsed.TotalSeconds; if (progressTimerTotalSeconds == 30) { ProgressTimer.Restart(); progress.Report(new FileSystemEnumerationProgress() { FileSystemEntries = fileSystemEntries.Count, CurrentFilePath = pathFileInfo.FullName }); } } } if (!pathFileInfo.Attributes.HasFlag(FileAttributes.Directory)) { throw new ArgumentException($"Path is not a directory: {pathFileInfo.FullName}"); } foreach (var fileSystemEntryPath in Directory.EnumerateFileSystemEntries( pathFileInfo.FullName, "*", SearchOption.TopDirectoryOnly)) { FileInfo childFileInfo = null; childFileInfo = new FileInfo(fileSystemEntryPath); FileInfo placeHolder = null; fileSystemEntries.AddOrUpdate(childFileInfo.FullName, childFileInfo, (TKey, TOldValue) => placeHolder); if (childFileInfo.Attributes.HasFlag(FileAttributes.Directory) && !childFileInfo.Attributes.HasFlag(FileAttributes.ReparsePoint)) { if (directoryExclusions.Any(x => childFileInfo.FullName.IndexOf(x, StringComparison.OrdinalIgnoreCase) > -1)) { continue; } tasks.Add(Task.Run(async() => { await GetFileSystemEntriesAsync( pathFileInfo: childFileInfo, tasks: tasks, progress: progress, directoryExclusions: directoryExclusions, fileSystemEntries: fileSystemEntries, continueOnUnauthorizedAccessExceptions: continueOnUnauthorizedAccessExceptions, continueOnPathTooLongExceptions: continueOnPathTooLongExceptions); })); } // if (childFileInfo.Attributes.HasFlag() } // foreach (var fileSystemEntryPath in Directory.EnumerateFileSystemEntries( } finally { lock (TasksCreatedCompletedLockObject) { TasksCompleted++; } } }); // await Task.Run(() => { } catch (UnauthorizedAccessException e) { Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine($"[ThreadId: {Thread.CurrentThread.ManagedThreadId}] {Extensions.CurrentMethodName()} pathFileInfo.FullName: {pathFileInfo.FullName} UnauthorizedAccessException: {e.Message ?? "NULL"}"); Console.ResetColor(); if (!continueOnUnauthorizedAccessExceptions) { throw; } } catch (PathTooLongException e) { Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine($"[ThreadId: {Thread.CurrentThread.ManagedThreadId}] {Extensions.CurrentMethodName()} pathFileInfo.FullName: {pathFileInfo.FullName} PathTooLongException: {e.Message ?? "NULL"}"); Console.ResetColor(); if (!continueOnPathTooLongExceptions) { throw; } } catch (AggregateException ae) { Debug.WriteLine($"InnerException count: {ae.Flatten().InnerExceptions.Count}"); } catch (Exception e) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine($"[ThreadId: {Thread.CurrentThread.ManagedThreadId}] {Extensions.CurrentMethodName()} path: {pathFileInfo.FullName} child path: {pathFileInfo.FullName} Exception: {e.VerboseExceptionString()}"); Console.ResetColor(); throw; } return(fileSystemEntries); }