using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; public class FileScanner { //all extensions and cuncurrent bag as a list wich works threw out multiple threads private readonly string[] _extensions; private readonly ConcurrentBag _foundFiles = new ConcurrentBag(); public FileScanner(string[] extensions) { _extensions = extensions.Select(e => e.ToLower()).ToArray(); } //return a list of all coneckted drives public async Task> ScanAllDrivesAsync() { var drives = new List(); foreach (var drive in DriveInfo.GetDrives()) { if (!drive.IsReady) continue; Console.WriteLine($"Scanning {drive.Name} ..."); string root = drive.RootDirectory.FullName; drives.Add(root); } return drives.ToList(); } //scan teh designated drive or folder public async Task> ScanDriveParallel(string rootPath) { //all sub direcktorys will be also added to this bag var folderQueue = new ConcurrentQueue(); folderQueue.Enqueue(rootPath); //all aktive skanners are placed here var folderWorkers = new List(); //keep max tasks at half teh amounts of cores int maxWorkers = Environment.ProcessorCount/2; for (int i = 0; i < maxWorkers; i++) { folderWorkers.Add(Task.Run(() => { while (folderQueue.TryDequeue(out string currentPath)) { try { // Check files foreach (var file in Directory.GetFiles(currentPath)) { if (_extensions.Any(ext => file.EndsWith(ext, StringComparison.OrdinalIgnoreCase))) { //Console.WriteLine(file); _foundFiles.Add(file); } } // Enqueue subdirectories foreach (var dir in Directory.GetDirectories(currentPath)) { folderQueue.Enqueue(dir); } } catch { // Skip inaccessible folders silently } } })); } //wait till all tasks are done Task.WaitAll(folderWorkers.ToArray()); //return the found paths as string return _foundFiles.ToList(); } }