/// <summary> /// Loads the XML files for each processor. /// </summary> /// <returns>All XML processors that were loaded successfully.</returns> private IEnumerable <XMLProcessor> SetupXMLProcessors() { foreach (var xmlProcessor in XMLProcessors.ToArray()) { if (xmlProcessor.LoadXMLFile() != ImproverStatus.LoadError) { yield return(xmlProcessor); } } }
/// <summary> /// Creates the XML Processors and adds them to the XMLProcessors collection. /// </summary> /// <param name="filenames">A list of the names of XML files to load.</param> public async Task AddFilesAsync(IEnumerable <string>?filenames) { if (filenames is null) { return; } #if DEBUG stopwatch.Restart(); #endif string errorMessage = string.Empty; var skippedFiles = new ConcurrentBag <string>(); var currentlyLoaded = XMLProcessors.ToArray(); var blockingCollection = new BlockingCollection <XMLProcessor>(); var loadingErrorMessageLock = new object(); var cd = new CompositeDisposable(XMLProcessors.SuspendCount(), blockingCollection); // Consumer blockingCollection.GetConsumingEnumerable() .ToObservable(TaskPoolScheduler.Default) .Buffer(5) .ObserveOn(RxApp.MainThreadScheduler) .Subscribe( onNext: xmlProcessors => XMLProcessors.AddRange(xmlProcessors), onCompleted: () => cd.Dispose() ); // Producers var loadingTasks = filenames.Select(fileFullPath => Task.Run(() => { if (!fileFullPath.EndsWith(".xml", StringComparison.OrdinalIgnoreCase)) { return; } string filename = Path.GetFileName(fileFullPath); if (filename.Contains("VOCAL") || filename.StartsWith("DDC") || filename.StartsWith("DD_")) { skippedFiles.Add(filename); return; } // Skip files that are already loaded if (currentlyLoaded.Any(f => f.XMLFileFullPath == fileFullPath)) { skippedFiles.Add(filename); return; } var processor = new XMLProcessor(fileFullPath); if (processor.Status == ImproverStatus.LoadError) { lock (loadingErrorMessageLock) { errorMessage += $"Error loading file {processor.XMLFileName}:{Environment.NewLine}{processor.StatusMessages[0].Message}{Environment.NewLine}"; } return; } blockingCollection.Add(processor); })); var completeTasks = Task.WhenAll(loadingTasks.ToArray()) .ContinueWith(_ => blockingCollection.CompleteAdding()); await completeTasks; #if DEBUG stopwatch.Stop(); ShowInStatusbar($"Loading time: {stopwatch.ElapsedMilliseconds} ms"); #endif if (!skippedFiles.IsEmpty) { UpdateStatusBarForSkippedFiles(skippedFiles); } if (errorMessage.Length > 0) { services.NotifyUser(errorMessage, "Error"); } }