Beispiel #1
0
        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);
        }