diff --git a/src/MaaWpfGui/Configuration/ConfigFactory.cs b/src/MaaWpfGui/Configuration/ConfigFactory.cs index 2eaa5d6adf..572351fc4a 100644 --- a/src/MaaWpfGui/Configuration/ConfigFactory.cs +++ b/src/MaaWpfGui/Configuration/ConfigFactory.cs @@ -18,6 +18,7 @@ using System.ComponentModel; using System.IO; using System.Text.Json; using System.Text.Json.Serialization; +using System.Threading; using System.Threading.Tasks; using MaaWpfGui.Helper; using ObservableCollections; @@ -36,7 +37,9 @@ namespace MaaWpfGui.Configuration private static readonly ILogger _logger = Log.ForContext(); - private static readonly object _lock = new object(); + private static readonly object _lock = new(); + + private static readonly SemaphoreSlim _semaphore = new(1, 1); public delegate void ConfigurationUpdateEventHandler(string key, object oldValue, object newValue); @@ -181,7 +184,7 @@ namespace MaaWpfGui.Configuration private static async void OnPropertyChanged(string key, object oldValue, object newValue) { - var result = await Save(); + var result = await SaveAsync(); if (result) { ConfigurationUpdateEvent?.Invoke(key, oldValue, newValue); @@ -193,33 +196,51 @@ namespace MaaWpfGui.Configuration } } - private static async Task Save(string file = null) + private static bool Save(string file = null) { - return await Task.Run(() => + lock (_lock) { - lock (_lock) + try { - try - { - File.WriteAllText(file ?? _configurationFile, JsonSerializer.Serialize(Root, _options)); - } - catch (Exception e) - { - _logger.Error(e, "Failed to save configuration file."); - return false; - } - - return true; + File.WriteAllText(file ?? _configurationFile, JsonSerializer.Serialize(Root, _options)); } - }); + catch (Exception e) + { + _logger.Error(e, "Failed to save configuration file."); + return false; + } + + return true; + } + } + + private static async Task SaveAsync(string file = null) + { + await _semaphore.WaitAsync(); + try + { + var filePath = file ?? _configurationFile; + var jsonString = JsonSerializer.Serialize(Root, _options); + await File.WriteAllTextAsync(filePath, jsonString); + return true; + } + catch (Exception e) + { + _logger.Error(e, "Failed to save configuration file."); + return false; + } + finally + { + _semaphore.Release(); + } } public static void Release() { lock (_lock) { - Save().Wait(); - Save(_configurationBakFile).Wait(); + Save(); + Save(_configurationBakFile); } } diff --git a/src/MaaWpfGui/Main/Bootstrapper.cs b/src/MaaWpfGui/Main/Bootstrapper.cs index f8fe979519..75b529fc67 100644 --- a/src/MaaWpfGui/Main/Bootstrapper.cs +++ b/src/MaaWpfGui/Main/Bootstrapper.cs @@ -23,6 +23,7 @@ using System.Windows.Interop; using System.Windows.Media; using System.Windows.Threading; using GlobalHotKey; +using MaaWpfGui.Configuration; using MaaWpfGui.Helper; using MaaWpfGui.Services; using MaaWpfGui.Services.HotKeys; @@ -224,6 +225,7 @@ namespace MaaWpfGui.Main ToastNotification.Cleanup(); ConfigurationHelper.Release(); + ConfigFactory.Release(); _logger.Information("MaaAssistantArknights GUI exited"); _logger.Information(string.Empty);