/// <summary> /// Example that will run freely and the app will be unresponsive which /// is how many developers approach reading folders and only try with a smaller /// folder structure but larger structures will freeze the app thus we /// need to consider an asynchronous method. /// </summary> /// <param name="path">Folder to work with</param> /// <param name="indentLevel">Indent level for display with Console.WriteLine</param> public static void RecursiveFolders(string path, int indentLevel) { try { if ((File.GetAttributes(path) & FileAttributes.ReparsePoint) != FileAttributes.ReparsePoint) { foreach (var folder in Directory.GetDirectories(path)) { OnTraverseEvent?.Invoke(folder); Console.WriteLine($"{new string(' ', indentLevel)}{Path.GetFileName(folder)}"); RecursiveFolders(folder, indentLevel + 2); } } } catch (UnauthorizedAccessException unauthorized) { OnExceptionEvent?.Invoke(unauthorized); } }
public static async Task RecursiveFolders(DirectoryInfo directoryInfo, string[] excludeFileExtensions, CancellationToken ct) { if (!directoryInfo.Exists) { OnTraverseEvent?.Invoke("Nothing to process"); return; } if (!excludeFileExtensions.Any(directoryInfo.FullName.Contains)) { await Task.Delay(1, ct); OnTraverseEvent?.Invoke(directoryInfo.FullName); } else { OnTraverseExcludeFolderEvent?.Invoke(directoryInfo.FullName); } DirectoryInfo folder = null; try { await Task.Run(async() => { foreach (DirectoryInfo dir in directoryInfo.EnumerateDirectories()) { folder = dir; if ((folder.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden || (folder.Attributes & FileAttributes.System) == FileAttributes.System || (folder.Attributes & FileAttributes.ReparsePoint) == FileAttributes.ReparsePoint) { OnTraverseExcludeFolderEvent?.Invoke($"* {folder.FullName}"); continue; } if (!Cancelled) { await Task.Delay(1); await RecursiveFolders(folder, excludeFileExtensions, ct); } else { return; } if (ct.IsCancellationRequested) { ct.ThrowIfCancellationRequested(); } } }, ct); } catch (Exception ex) { if (ex is OperationCanceledException) { Cancelled = true; } else if (ex is UnauthorizedAccessException) { UnauthorizedAccessExceptionEvent?.Invoke($"Access denied '{ex.Message}'"); } else { OnExceptionEvent?.Invoke(ex); } } }