From 5ca76521f81e3613844616368c3fc7aacaf634b2 Mon Sep 17 00:00:00 2001 From: DismissedLight <1686188646@qq.com> Date: Thu, 12 Sep 2024 17:25:26 +0800 Subject: [PATCH] Dialog enqueued block --- .../Http/Sharding/HttpShardCopyWorkerOptions.cs | 8 +------- .../Core/Threading/SemaphoreSlimExtension.cs | 2 -- .../Factory/ContentDialog/ContentDialogFactory.cs | 14 +++++++++----- .../ContentDialog/IContentDialogFactory.cs | 4 +++- .../Service/AvatarInfo/AvatarInfoService.cs | 15 --------------- .../Service/GachaLog/GachaLogService.cs | 2 +- .../LaunchExecutionEnsureGameResourceHandler.cs | 2 +- .../Service/Navigation/INavigationAwaiter.cs | 4 ---- .../UI/Xaml/Control/ContentDialogExtension.cs | 11 +++++++++++ .../ViewModel/Achievement/AchievementImporter.cs | 2 +- .../AvatarProperty/AvatarPropertyViewModel.cs | 4 ++-- .../ViewModel/Cultivation/CultivationViewModel.cs | 2 +- .../ViewModel/DailyNote/DailyNoteViewModel.cs | 2 +- .../ViewModel/GachaLog/GachaLogViewModel.cs | 2 +- .../ViewModel/GachaLog/HutaoCloudViewModel.cs | 2 +- .../ViewModel/Setting/SettingStorageViewModel.cs | 2 +- .../Snap.Hutao/ViewModel/TitleViewModel.cs | 2 +- .../Snap.Hutao/Web/Bridge/MiHoYoJSBridgeFacade.cs | 5 ++--- 18 files changed, 37 insertions(+), 48 deletions(-) diff --git a/src/Snap.Hutao/Snap.Hutao/Core/IO/Http/Sharding/HttpShardCopyWorkerOptions.cs b/src/Snap.Hutao/Snap.Hutao/Core/IO/Http/Sharding/HttpShardCopyWorkerOptions.cs index 6bdca9621e..50e639f407 100644 --- a/src/Snap.Hutao/Snap.Hutao/Core/IO/Http/Sharding/HttpShardCopyWorkerOptions.cs +++ b/src/Snap.Hutao/Snap.Hutao/Core/IO/Http/Sharding/HttpShardCopyWorkerOptions.cs @@ -51,13 +51,7 @@ public string DestinationFilePath } } - public SafeFileHandle DestinationFileHandle - { - get - { - return destinationFileHandle ??= GetFileHandle(); - } - } + public SafeFileHandle DestinationFileHandle { get => destinationFileHandle ??= GetFileHandle(); } public long ContentLength { diff --git a/src/Snap.Hutao/Snap.Hutao/Core/Threading/SemaphoreSlimExtension.cs b/src/Snap.Hutao/Snap.Hutao/Core/Threading/SemaphoreSlimExtension.cs index cc4f7a5265..870ecc5a18 100644 --- a/src/Snap.Hutao/Snap.Hutao/Core/Threading/SemaphoreSlimExtension.cs +++ b/src/Snap.Hutao/Snap.Hutao/Core/Threading/SemaphoreSlimExtension.cs @@ -7,7 +7,6 @@ namespace Snap.Hutao.Core.Threading; internal static class SemaphoreSlimExtension { - [Obsolete("Use AsyncLock instead")] public static async ValueTask EnterAsync(this SemaphoreSlim semaphoreSlim, CancellationToken token = default) { try @@ -22,7 +21,6 @@ public static async ValueTask EnterAsync(this SemaphoreSlim return new SemaphoreSlimToken(semaphoreSlim); } - [Obsolete("Use AsyncLock instead")] public static SemaphoreSlimToken Enter(this SemaphoreSlim semaphoreSlim) { try diff --git a/src/Snap.Hutao/Snap.Hutao/Factory/ContentDialog/ContentDialogFactory.cs b/src/Snap.Hutao/Snap.Hutao/Factory/ContentDialog/ContentDialogFactory.cs index 1249036133..cee4090db7 100644 --- a/src/Snap.Hutao/Snap.Hutao/Factory/ContentDialog/ContentDialogFactory.cs +++ b/src/Snap.Hutao/Snap.Hutao/Factory/ContentDialog/ContentDialogFactory.cs @@ -34,6 +34,8 @@ public bool IsDialogShowing } } + public ITaskContext TaskContext { get => taskContext; } + public async ValueTask CreateForConfirmAsync(string title, string content) { await taskContext.SwitchToMainThreadAsync(); @@ -108,20 +110,22 @@ public TContentDialog CreateInstance(params object[] parameters) [SuppressMessage("", "SH003")] [SuppressMessage("", "SH100")] - public Task EnqueueAndShowAsync(Microsoft.UI.Xaml.Controls.ContentDialog contentDialog) + public Task EnqueueAndShowAsync(Microsoft.UI.Xaml.Controls.ContentDialog contentDialog, TaskCompletionSource? dialogShowSource = default) { - TaskCompletionSource dialogShowCompletionSource = new(); + TaskCompletionSource dialogResultSource = new(); dialogQueue.Enqueue(async () => { try { + await taskContext.SwitchToMainThreadAsync(); + dialogShowSource?.TrySetResult(); ContentDialogResult result = await contentDialog.ShowAsync(); - dialogShowCompletionSource.SetResult(result); + dialogResultSource.SetResult(result); } catch (Exception ex) { - dialogShowCompletionSource.SetException(ex); + dialogResultSource.SetException(ex); } finally { @@ -134,7 +138,7 @@ public Task EnqueueAndShowAsync(Microsoft.UI.Xaml.Controls. ShowNextDialog(); } - return dialogShowCompletionSource.Task; + return dialogResultSource.Task; Task ShowNextDialog() { diff --git a/src/Snap.Hutao/Snap.Hutao/Factory/ContentDialog/IContentDialogFactory.cs b/src/Snap.Hutao/Snap.Hutao/Factory/ContentDialog/IContentDialogFactory.cs index 219d510e02..eed622fea5 100644 --- a/src/Snap.Hutao/Snap.Hutao/Factory/ContentDialog/IContentDialogFactory.cs +++ b/src/Snap.Hutao/Snap.Hutao/Factory/ContentDialog/IContentDialogFactory.cs @@ -13,6 +13,8 @@ internal interface IContentDialogFactory { bool IsDialogShowing { get; } + ITaskContext TaskContext { get; } + /// /// 异步确认 /// @@ -44,5 +46,5 @@ ValueTask CreateInstanceAsync(params object[] pa where TContentDialog : Microsoft.UI.Xaml.Controls.ContentDialog; [SuppressMessage("", "SH003")] - Task EnqueueAndShowAsync(Microsoft.UI.Xaml.Controls.ContentDialog contentDialog); + Task EnqueueAndShowAsync(Microsoft.UI.Xaml.Controls.ContentDialog contentDialog, TaskCompletionSource? dialogShowSource = default); } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/AvatarInfoService.cs b/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/AvatarInfoService.cs index 7809f33520..14adad162c 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/AvatarInfoService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/AvatarInfoService.cs @@ -6,9 +6,6 @@ using Snap.Hutao.Service.Metadata; using Snap.Hutao.ViewModel.AvatarProperty; using Snap.Hutao.ViewModel.User; -using Snap.Hutao.Web.Enka; -using Snap.Hutao.Web.Enka.Model; -using Snap.Hutao.Web.Hoyolab; using EntityAvatarInfo = Snap.Hutao.Model.Entity.AvatarInfo; namespace Snap.Hutao.Service.AvatarInfo; @@ -20,7 +17,6 @@ internal sealed partial class AvatarInfoService : IAvatarInfoService { private readonly AvatarInfoRepositoryOperation avatarInfoDbBulkOperation; private readonly IAvatarInfoRepository avatarInfoRepository; - private readonly IServiceScopeFactory serviceScopeFactory; private readonly ILogger logger; private readonly IMetadataService metadataService; private readonly ISummaryFactory summaryFactory; @@ -50,17 +46,6 @@ internal sealed partial class AvatarInfoService : IAvatarInfoService } } - private async ValueTask GetEnkaResponseAsync(PlayerUid uid, CancellationToken token = default) - { - using (IServiceScope scope = serviceScopeFactory.CreateScope()) - { - EnkaClient enkaClient = scope.ServiceProvider.GetRequiredService(); - - return await enkaClient.GetForwardDataAsync(uid, token).ConfigureAwait(false) - ?? await enkaClient.GetDataAsync(uid, token).ConfigureAwait(false); - } - } - private async ValueTask GetSummaryCoreAsync(IEnumerable avatarInfos, CancellationToken token) { using (ValueStopwatch.MeasureExecution(logger)) diff --git a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogService.cs b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogService.cs index cb51fbf71a..e318ed7919 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogService.cs @@ -195,7 +195,7 @@ public async ValueTask EnsureArchiveInCollectionAsync(Guid archive // save items for each queryType token.ThrowIfCancellationRequested(); fetchContext.SaveItems(); - await Task.Delay((int)(System.Random.Shared.NextDouble() * (2000 - 1000)) + 1000).ConfigureAwait(false); + await Task.Delay((int)(System.Random.Shared.NextDouble() * (2000 - 1000)) + 1000, token).ConfigureAwait(false); } } diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Game/Launching/Handler/LaunchExecutionEnsureGameResourceHandler.cs b/src/Snap.Hutao/Snap.Hutao/Service/Game/Launching/Handler/LaunchExecutionEnsureGameResourceHandler.cs index d29cd85ed5..e346d2e2bc 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Game/Launching/Handler/LaunchExecutionEnsureGameResourceHandler.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Game/Launching/Handler/LaunchExecutionEnsureGameResourceHandler.cs @@ -37,7 +37,7 @@ public async ValueTask OnExecutionAsync(LaunchExecutionContext context, LaunchEx LaunchGamePackageConvertDialog dialog = await contentDialogFactory.CreateInstanceAsync().ConfigureAwait(false); IProgress convertProgress = progressFactory.CreateForMainThread(state => dialog.State = state); - using (await dialog.BlockAsync(context.TaskContext).ConfigureAwait(false)) + using (await dialog.BlockAsync(contentDialogFactory).ConfigureAwait(false)) { if (!await EnsureGameResourceAsync(context, gameFileSystem, convertProgress).ConfigureAwait(false)) { diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Navigation/INavigationAwaiter.cs b/src/Snap.Hutao/Snap.Hutao/Service/Navigation/INavigationAwaiter.cs index ec1255f89b..2e0fee5db8 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Navigation/INavigationAwaiter.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Navigation/INavigationAwaiter.cs @@ -3,10 +3,6 @@ namespace Snap.Hutao.Service.Navigation; -/// -/// 表示导航等待器 -/// -[HighQuality] internal interface INavigationAwaiter { /// diff --git a/src/Snap.Hutao/Snap.Hutao/UI/Xaml/Control/ContentDialogExtension.cs b/src/Snap.Hutao/Snap.Hutao/UI/Xaml/Control/ContentDialogExtension.cs index 97dbf566bb..e433037457 100644 --- a/src/Snap.Hutao/Snap.Hutao/UI/Xaml/Control/ContentDialogExtension.cs +++ b/src/Snap.Hutao/Snap.Hutao/UI/Xaml/Control/ContentDialogExtension.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. using Microsoft.UI.Xaml.Controls; +using Snap.Hutao.Factory.ContentDialog; namespace Snap.Hutao.UI.Xaml.Control; @@ -17,6 +18,8 @@ internal static class ContentDialogExtension /// 对话框 /// 任务上下文 /// 用于恢复用户交互 + [Obsolete("Use another overload")] + [SuppressMessage("", "SH100")] public static async ValueTask BlockAsync(this ContentDialog contentDialog, ITaskContext taskContext) { await taskContext.SwitchToMainThreadAsync(); @@ -26,4 +29,12 @@ public static async ValueTask BlockAsync(this ContentDialog _ = contentDialog.ShowAsync(); return new ContentDialogScope(contentDialog, taskContext); } + + public static async ValueTask BlockAsync(this ContentDialog contentDialog, IContentDialogFactory contentDialogFactory) + { + TaskCompletionSource dialogShowSource = new(); + _ = contentDialogFactory.EnqueueAndShowAsync(contentDialog, dialogShowSource); + await dialogShowSource.Task.ConfigureAwait(false); + return new ContentDialogScope(contentDialog, contentDialogFactory.TaskContext); + } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/Achievement/AchievementImporter.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/Achievement/AchievementImporter.cs index 7ccfd2402e..76a28818f2 100644 --- a/src/Snap.Hutao/Snap.Hutao/ViewModel/Achievement/AchievementImporter.cs +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/Achievement/AchievementImporter.cs @@ -100,7 +100,7 @@ private async ValueTask TryImportCoreAsync(AchievementViewModelScopeContex .ConfigureAwait(false); ImportResult result; - using (await dialog.BlockAsync(scopeContext.TaskContext).ConfigureAwait(false)) + using (await dialog.BlockAsync(scopeContext.ContentDialogFactory).ConfigureAwait(false)) { result = await context.AchievementService.ImportFromUIAFAsync(archive, uiaf.List, strategy).ConfigureAwait(false); } diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/AvatarProperty/AvatarPropertyViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/AvatarProperty/AvatarPropertyViewModel.cs index e4f7f1380f..253878b771 100644 --- a/src/Snap.Hutao/Snap.Hutao/ViewModel/AvatarProperty/AvatarPropertyViewModel.cs +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/AvatarProperty/AvatarPropertyViewModel.cs @@ -82,7 +82,7 @@ private async Task RefreshCoreAsync(UserAndUid userAndUid, RefreshOption option, .CreateForIndeterminateProgressAsync(SH.ViewModelAvatarPropertyFetch) .ConfigureAwait(false); - using (await dialog.BlockAsync(scopeContext.TaskContext).ConfigureAwait(false)) + using (await dialog.BlockAsync(scopeContext.ContentDialogFactory).ConfigureAwait(false)) { summaryResult = await scopeContext.AvatarInfoService .GetSummaryAsync(userAndUid, option, token) @@ -203,7 +203,7 @@ private async Task BatchCultivateAsync() .ConfigureAwait(false); BatchCultivateResult result = default; - using (await progressDialog.BlockAsync(scopeContext.TaskContext).ConfigureAwait(false)) + using (await progressDialog.BlockAsync(scopeContext.ContentDialogFactory).ConfigureAwait(false)) { List deltas = []; foreach (AvatarView avatar in avatars) diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/Cultivation/CultivationViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/Cultivation/CultivationViewModel.cs index f9c0084c92..cff366f906 100644 --- a/src/Snap.Hutao/Snap.Hutao/ViewModel/Cultivation/CultivationViewModel.cs +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/Cultivation/CultivationViewModel.cs @@ -230,7 +230,7 @@ private async Task RefreshInventoryAsync() .CreateForIndeterminateProgressAsync(SH.ViewModelCultivationRefreshInventoryProgress) .ConfigureAwait(false); - using (await dialog.BlockAsync(taskContext).ConfigureAwait(false)) + using (await dialog.BlockAsync(contentDialogFactory).ConfigureAwait(false)) { await inventoryService.RefreshInventoryAsync(Projects.CurrentItem).ConfigureAwait(false); diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/DailyNote/DailyNoteViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/DailyNote/DailyNoteViewModel.cs index 8f893ccfd0..d64e1760fe 100644 --- a/src/Snap.Hutao/Snap.Hutao/ViewModel/DailyNote/DailyNoteViewModel.cs +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/DailyNote/DailyNoteViewModel.cs @@ -85,7 +85,7 @@ private async Task TrackCurrentUserAndUidAsync() .CreateForIndeterminateProgressAsync(SH.ViewModelDailyNoteRequestProgressTitle) .ConfigureAwait(false); - using (await dialog.BlockAsync(taskContext).ConfigureAwait(false)) + using (await dialog.BlockAsync(contentDialogFactory).ConfigureAwait(false)) { await dailyNoteService.AddDailyNoteAsync(userAndUid).ConfigureAwait(false); } diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/GachaLog/GachaLogViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/GachaLog/GachaLogViewModel.cs index 3e35e6c989..5f5f2758b0 100644 --- a/src/Snap.Hutao/Snap.Hutao/ViewModel/GachaLog/GachaLogViewModel.cs +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/GachaLog/GachaLogViewModel.cs @@ -163,7 +163,7 @@ private async ValueTask RefreshCoreAsync(RefreshOption option) ContentDialogScope hideToken; try { - hideToken = await dialog.BlockAsync(taskContext).ConfigureAwait(false); + hideToken = await dialog.BlockAsync(contentDialogFactory).ConfigureAwait(false); } catch (COMException ex) { diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/GachaLog/HutaoCloudViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/GachaLog/HutaoCloudViewModel.cs index b6f7df122b..70fd68643e 100644 --- a/src/Snap.Hutao/Snap.Hutao/ViewModel/GachaLog/HutaoCloudViewModel.cs +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/GachaLog/HutaoCloudViewModel.cs @@ -90,7 +90,7 @@ private async Task UploadAsync(GachaArchive? gachaArchive) bool isOk; string message; - using (await dialog.BlockAsync(taskContext).ConfigureAwait(false)) + using (await dialog.BlockAsync(contentDialogFactory).ConfigureAwait(false)) { (isOk, message) = await hutaoCloudService.UploadGachaItemsAsync(gachaArchive).ConfigureAwait(false); } diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/Setting/SettingStorageViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/Setting/SettingStorageViewModel.cs index a0ae369e69..64e54843b1 100644 --- a/src/Snap.Hutao/Snap.Hutao/ViewModel/Setting/SettingStorageViewModel.cs +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/Setting/SettingStorageViewModel.cs @@ -83,7 +83,7 @@ private async Task ResetStaticResource() .CreateForIndeterminateProgressAsync(SH.ViewModelSettingResetStaticResourceProgress) .ConfigureAwait(false); - await using (await dialog.BlockAsync(taskContext).ConfigureAwait(false)) + await using (await dialog.BlockAsync(contentDialogFactory).ConfigureAwait(false)) { await taskContext.SwitchToBackgroundAsync(); StaticResource.FailAll(); diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/TitleViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/TitleViewModel.cs index 90c5288d11..6210a9482f 100644 --- a/src/Snap.Hutao/Snap.Hutao/ViewModel/TitleViewModel.cs +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/TitleViewModel.cs @@ -137,7 +137,7 @@ private async ValueTask DoCheckUpdateAsync() ContentDialog contentDialog = await contentDialogFactory .CreateForIndeterminateProgressAsync(SH.ViewTitleUpdatePackageInstallingContent) .ConfigureAwait(false); - using (await contentDialog.BlockAsync(taskContext).ConfigureAwait(false)) + using (await contentDialog.BlockAsync(contentDialogFactory).ConfigureAwait(false)) { if (launchUpdaterResult.Process is { } updater) { diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Bridge/MiHoYoJSBridgeFacade.cs b/src/Snap.Hutao/Snap.Hutao/Web/Bridge/MiHoYoJSBridgeFacade.cs index 71b3915784..21be34ffa1 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Bridge/MiHoYoJSBridgeFacade.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Bridge/MiHoYoJSBridgeFacade.cs @@ -20,7 +20,6 @@ namespace Snap.Hutao.Web.Bridge; [HighQuality] -[SuppressMessage("", "CA1001")] internal class MiHoYoJSBridgeFacade { private const string InitializeJsInterfaceScript = """ @@ -76,7 +75,7 @@ function mouseListener (e, event) { document.addEventListener('mousedown', mouseDownListener); """; - private readonly SemaphoreSlim webMessageSemaphore = new(1); + private readonly AsyncLock webMessageLock = new(); private readonly Guid bridgeId = Guid.NewGuid(); private readonly UserAndUid userAndUid; @@ -406,7 +405,7 @@ private async void OnWebMessageReceived(CoreWebView2 webView2, CoreWebView2WebMe ArgumentNullException.ThrowIfNull(param); logger.LogInformation("[OnMessage]\nMethod : {method}\nPayload : {payload}\nCallback: {callback}", param.Method, param.Payload, param.Callback); - using (await webMessageSemaphore.EnterAsync().ConfigureAwait(false)) + using (await webMessageLock.LockAsync().ConfigureAwait(false)) { IJsBridgeResult? result = await TryGetJsResultFromJsParamAsync(param).ConfigureAwait(false);