public async Task Run(DirectoryInfo sourceDirectory, string outputDirectoryName, bool testRun, int workers) { _logger.LogInformation("Validating Source Directory {dir}", sourceDirectory.FullName); _logger.LogInformation("Setting output paths to {dirname}", outputDirectoryName); Stopwatch stopwatch = new(); stopwatch.Start(); await Task.WhenAll( LoadBranches(sourceDirectory, outputDirectoryName, testRun), LoadNcAgencies(sourceDirectory, outputDirectoryName, testRun), LoadNmAgencies(sourceDirectory, outputDirectoryName, testRun), LoadSrcn(sourceDirectory, outputDirectoryName, testRun), LoadMbdot(sourceDirectory, outputDirectoryName, testRun) ); _progress.SetFilesToProcessCount(await _processingQueue.CurrentCount()); _logger.LogInformation("Queue Loaded: {queue}", _processingQueue.ToString()); var workerPool = Enumerable.Range(0, workers).Select(_ => _services.GetRequiredService <FileProcessor>()); var workerTasks = workerPool.Select(w => w.StartAsync(_workerTokenSource.Token)); await Task.WhenAll(workerTasks); // HACK Need to figure out a better way to determine the end of processing bool running = true; while (running) { await Task.Delay(3000); running = await _processingQueue.CurrentCount() > 0; } stopwatch.Stop(); _logger.LogInformation("Stats:\n\tElapsed Time:\t{time} ms\n\tFiles Attempted:\t{at} files\n\tFiles Copied:\t{cp} files\n\tWorker Count:\t{w}", stopwatch.ElapsedMilliseconds, _progress.FilesAttempted, _progress.FilesProcessed, workers); var stopTasks = workerPool.Select(w => w.StopAsync(_workerTokenSource.Token)); await Task.WhenAll(stopTasks); await Finalize(); }