[App] Refactor importing DAT folder to use parallel foreach.

This commit is contained in:
2025-07-29 21:33:57 +01:00
parent 475da761a5
commit 2382187960
2 changed files with 50 additions and 66 deletions

View File

@@ -1,5 +1,4 @@
using System; using System;
using System.Threading.Tasks;
using Avalonia.Media; using Avalonia.Media;
using Avalonia.Threading; using Avalonia.Threading;
using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.ComponentModel;
@@ -22,8 +21,6 @@ public partial class DatImporter : ObservableObject
[ObservableProperty] [ObservableProperty]
string _statusMessage; string _statusMessage;
public string Filename { get; internal init; } public string Filename { get; internal init; }
public Task Task { get; set; }
public bool Running { get; private set; } = true;
internal void OnErrorOccurred(object sender, ErrorEventArgs e) => Dispatcher.UIThread.Post(() => internal void OnErrorOccurred(object sender, ErrorEventArgs e) => Dispatcher.UIThread.Post(() =>
{ {
@@ -59,6 +56,5 @@ public partial class DatImporter : ObservableObject
Minimum = 0; Minimum = 0;
Progress = 1; Progress = 1;
StatusMessage = e.Message; StatusMessage = e.Message;
Running = false;
}); });
} }

View File

@@ -4,6 +4,7 @@ using System.Collections.ObjectModel;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Input; using System.Windows.Input;
using Avalonia.Controls; using Avalonia.Controls;
@@ -50,7 +51,6 @@ public sealed partial class ImportDatFolderViewModel : ViewModelBase
bool _recursiveChecked; bool _recursiveChecked;
[ObservableProperty] [ObservableProperty]
string _statusMessage; string _statusMessage;
int _workers;
public ImportDatFolderViewModel() public ImportDatFolderViewModel()
{ {
@@ -100,75 +100,63 @@ public sealed partial class ImportDatFolderViewModel : ViewModelBase
CanStart = false; CanStart = false;
IsReady = false; IsReady = false;
IsImporting = true; IsImporting = true;
_workers = 0;
_stopwatch.Restart(); _stopwatch.Restart();
Import(); _ = Task.Run(Import);
} }
void Import() void Import()
{ {
Parallel.ForEach(_datFiles,
new ParallelOptions
{
MaxDegreeOfParallelism = Environment.ProcessorCount
},
datFile =>
{
Dispatcher.UIThread.Post(() =>
{
StatusMessage = string.Format(Localization.ImportingItem, Path.GetFileName(datFile));
ProgressValue = _listPosition;
});
var model = new DatImporter
{
Filename = Path.GetFileName(datFile),
Minimum = 0,
Maximum = _datFiles.Length,
Progress = 0,
Indeterminate = false
};
var worker = new Core.Workers.DatImporter(datFile,
Category,
new SerilogLoggerFactory(Log.Logger));
worker.ErrorOccurred += model.OnErrorOccurred;
worker.SetIndeterminateProgress += model.OnSetIndeterminateProgress;
worker.SetMessage += model.OnSetMessage;
worker.SetProgress += model.OnSetProgress;
worker.SetProgressBounds += model.OnSetProgressBounds;
worker.WorkFinished += model.OnWorkFinished;
worker.RomSetAdded += RomSetAdded;
Dispatcher.UIThread.Post(() => Importers.Add(model));
worker.Import();
Interlocked.Increment(ref _listPosition);
});
Dispatcher.UIThread.Post(() => Dispatcher.UIThread.Post(() =>
{ {
if(_listPosition >= _datFiles.Length) ProgressVisible = false;
{ StatusMessage = Localization.Finished;
if(_workers != 0) return; CanClose = true;
CanStart = false;
ProgressVisible = false; IsReady = true;
StatusMessage = Localization.Finished; _stopwatch.Stop();
CanClose = true;
CanStart = false;
IsReady = true;
_stopwatch.Stop();
return;
}
StatusMessage = string.Format(Localization.ImportingItem, Path.GetFileName(_datFiles[_listPosition]));
ProgressValue = _listPosition;
var model = new DatImporter
{
Filename = Path.GetFileName(_datFiles[_listPosition]),
Minimum = 0,
Maximum = _datFiles.Length,
Progress = 0,
Indeterminate = false
};
var worker =
new Core.Workers.DatImporter(_datFiles[_listPosition], Category, new SerilogLoggerFactory(Log.Logger));
worker.ErrorOccurred += model.OnErrorOccurred;
worker.SetIndeterminateProgress += model.OnSetIndeterminateProgress;
worker.SetMessage += model.OnSetMessage;
worker.SetProgress += model.OnSetProgress;
worker.SetProgressBounds += model.OnSetProgressBounds;
worker.WorkFinished += model.OnWorkFinished;
worker.RomSetAdded += RomSetAdded;
worker.WorkFinished += (_, _) =>
{
_workers--;
if(_workers < Environment.ProcessorCount) Import();
};
worker.ErrorOccurred += (_, _) =>
{
_workers--;
if(_workers < Environment.ProcessorCount) Import();
};
Importers.Add(model);
model.Task = Task.Run(worker.Import);
_workers++;
_listPosition++;
if(_workers < Environment.ProcessorCount) Import();
}); });
} }