/// <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> /// Removes the currently selected file(s) from the XML processor list. /// </summary> private void CloseFileImpl() { if (SelectedItems is null) { return; } foreach (var processor in SelectedItems.Cast <XMLProcessor>().ToArray()) { XMLProcessors.Remove(processor); } SelectedItems = null; }
private void SetupObservables() { // Keep the maximum value of the progressbar up to date this.WhenAnyValue(x => x.XMLProcessors.Count) .Where(c => c > 0) .Subscribe(count => ProgressMaximum = count * XMLProcessor.ProgressSteps); ProcessFiles.IsExecuting.ToPropertyEx(this, x => x.IsProcessingFiles, deferSubscription: false); OpenChildWindow = ShowWindow. Merge( ProcessFiles .Where(_ => XMLProcessors.Sum(processor => processor.StatusMessages.Count) > 0) .Select(_ => WindowType.ProcessingMessages) ); }
private async Task LoadFilesImpl(bool addingFiles = false) { if (!addingFiles && IsProcessingFiles) { return; } var fileNames = await services .OpenFileDialog( "Select RS2014 XML Arrangement(s)", FileFilter.RSXmlFiles, multiSelect : true); if (fileNames?.Length > 0) { if (!addingFiles) { XMLProcessors.Clear(); } await AddFilesAsync(fileNames).ConfigureAwait(false); } }
/// <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"); } }
private void CloseAllImpl() { XMLProcessors.Clear(); GC.Collect(2, GCCollectionMode.Optimized); GC.WaitForPendingFinalizers(); }