From 72a1ec2122c028f2fdae686aa83599e910d1d428 Mon Sep 17 00:00:00 2001 From: DismissedLight <1686188646@qq.com> Date: Sat, 6 Jul 2024 09:53:30 +0800 Subject: [PATCH] fix #1791 #1794 --- .../Core/Threading/VolatileWrite.cs | 22 ++++++++++ .../Service/GachaLog/GachaLogService.cs | 1 + .../Service/GachaLog/UIGFImportService.cs | 2 + .../ViewModel/GachaLog/GachaLogViewModel.cs | 42 +++++++++++++++---- 4 files changed, 58 insertions(+), 9 deletions(-) create mode 100644 src/Snap.Hutao/Snap.Hutao/Core/Threading/VolatileWrite.cs diff --git a/src/Snap.Hutao/Snap.Hutao/Core/Threading/VolatileWrite.cs b/src/Snap.Hutao/Snap.Hutao/Core/Threading/VolatileWrite.cs new file mode 100644 index 00000000..5e8f98c5 --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/Core/Threading/VolatileWrite.cs @@ -0,0 +1,22 @@ +// Copyright (c) DGP Studio. All rights reserved. +// Licensed under the MIT license. + +namespace Snap.Hutao.Core.Threading; + +internal readonly ref struct VolatileWrite +{ + private readonly ref bool reference; + private readonly bool initialState; + + public VolatileWrite(ref bool reference, bool initialState) + { + this.reference = ref reference; + this.initialState = initialState; + Volatile.Write(ref this.reference, initialState); + } + + public void Dispose() + { + Volatile.Write(ref reference, !initialState); + } +} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogService.cs b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogService.cs index a7edb596..03ffffa7 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogService.cs @@ -109,6 +109,7 @@ internal sealed partial class GachaLogService : IGachaLogService if (target is not null && Archives is not null) { + await taskContext.SwitchToMainThreadAsync(); Archives.CurrentItem = target; } diff --git a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/UIGFImportService.cs b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/UIGFImportService.cs index fe1bfaa3..ca20e340 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/UIGFImportService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/UIGFImportService.cs @@ -83,6 +83,8 @@ internal sealed partial class UIGFImportService : IUIGFImportService } gachaLogDbService.AddGachaItemRange(fullItems); + + await taskContext.SwitchToMainThreadAsync(); archives.MoveCurrentTo(archive); } diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/GachaLog/GachaLogViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/GachaLog/GachaLogViewModel.cs index 78d3da8e..ea1ff2b0 100644 --- a/src/Snap.Hutao/Snap.Hutao/ViewModel/GachaLog/GachaLogViewModel.cs +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/GachaLog/GachaLogViewModel.cs @@ -39,6 +39,7 @@ internal sealed partial class GachaLogViewModel : Abstraction.ViewModel private AdvancedDbCollectionView? archives; private GachaStatistics? statistics; private bool isAggressiveRefresh; + private bool suppressCurrentItemChangedHandling; public AdvancedDbCollectionView? Archives { @@ -119,25 +120,30 @@ internal sealed partial class GachaLogViewModel : Abstraction.ViewModel private void OnCurrentArchiveChanged(object? sender, object? e) { + if (suppressCurrentItemChangedHandling) + { + return; + } + UpdateStatisticsAsync(Archives?.CurrentItem).SafeForget(logger); } [Command("RefreshByWebCacheCommand")] - private Task RefreshByWebCacheAsync() + private async Task RefreshByWebCacheAsync() { - return RefreshCoreAsync(RefreshOption.WebCache).AsTask(); + await RefreshCoreAsync(RefreshOption.WebCache).ConfigureAwait(false); } [Command("RefreshBySTokenCommand")] - private Task RefreshBySTokenAsync() + private async Task RefreshBySTokenAsync() { - return RefreshCoreAsync(RefreshOption.SToken).AsTask(); + await RefreshCoreAsync(RefreshOption.SToken).ConfigureAwait(false); } [Command("RefreshByManualInputCommand")] - private Task RefreshByManualInputAsync() + private async Task RefreshByManualInputAsync() { - return RefreshCoreAsync(RefreshOption.ManualInput).AsTask(); + await RefreshCoreAsync(RefreshOption.ManualInput).ConfigureAwait(false); } private async ValueTask RefreshCoreAsync(RefreshOption option) @@ -184,7 +190,16 @@ internal sealed partial class GachaLogViewModel : Abstraction.ViewModel { try { - authkeyValid = await gachaLogService.RefreshGachaLogAsync(query, strategy, progress, CancellationToken).ConfigureAwait(false); + try + { + suppressCurrentItemChangedHandling = true; + authkeyValid = await gachaLogService.RefreshGachaLogAsync(query, strategy, progress, CancellationToken).ConfigureAwait(false); + } + finally + { + suppressCurrentItemChangedHandling = false; + await UpdateStatisticsAsync(Archives?.CurrentItem).ConfigureAwait(false); + } } catch (HutaoException ex) { @@ -339,7 +354,7 @@ internal sealed partial class GachaLogViewModel : Abstraction.ViewModel private async ValueTask TryImportUIGFInternalAsync(UIGF uigf) { - if (!uigf.IsCurrentVersionSupported(out UIGFVersion version)) + if (!uigf.IsCurrentVersionSupported(out _)) { infoBarService.Warning(SH.ViewModelGachaLogImportWarningTitle, SH.ViewModelGachaLogImportWarningMessage); return false; @@ -357,7 +372,16 @@ internal sealed partial class GachaLogViewModel : Abstraction.ViewModel { using (await dialog.BlockAsync(taskContext).ConfigureAwait(false)) { - await gachaLogService.ImportFromUIGFAsync(uigf).ConfigureAwait(false); + try + { + suppressCurrentItemChangedHandling = true; + await gachaLogService.ImportFromUIGFAsync(uigf).ConfigureAwait(false); + } + finally + { + suppressCurrentItemChangedHandling = false; + await UpdateStatisticsAsync(Archives?.CurrentItem).ConfigureAwait(false); + } } } catch (InvalidOperationException ex)