From 7aa9fa1a36da72d3651de72bf24b0b1ea157fde0 Mon Sep 17 00:00:00 2001 From: Robert Date: Sun, 26 Feb 2023 15:22:02 +0100 Subject: [PATCH] Improve cancelling builds --- .../WindowsUpdateNotificationProvider.cs | 49 +++++++++++++------ .../Settings/Updating/ReleaseViewModel.cs | 6 +-- .../Updating/IUpdateNotificationProvider.cs | 2 +- .../InAppUpdateNotificationProvider.cs | 2 +- .../Services/Updating/UpdateService.cs | 6 +-- 5 files changed, 40 insertions(+), 25 deletions(-) diff --git a/src/Artemis.UI.Windows/Providers/WindowsUpdateNotificationProvider.cs b/src/Artemis.UI.Windows/Providers/WindowsUpdateNotificationProvider.cs index 3cc68f83f..79ab75e57 100644 --- a/src/Artemis.UI.Windows/Providers/WindowsUpdateNotificationProvider.cs +++ b/src/Artemis.UI.Windows/Providers/WindowsUpdateNotificationProvider.cs @@ -20,6 +20,7 @@ public class WindowsUpdateNotificationProvider : IUpdateNotificationProvider private readonly Func _getSettingsViewModel; private readonly IMainWindowService _mainWindowService; private readonly IUpdateService _updateService; + private CancellationTokenSource? _cancellationTokenSource; public WindowsUpdateNotificationProvider(IMainWindowService mainWindowService, IUpdateService updateService, @@ -46,15 +47,15 @@ public class WindowsUpdateNotificationProvider : IUpdateNotificationProvider await InstallRelease(releaseId, releaseVersion); else if (action == "view-changes") ViewRelease(releaseId); + else if (action == "cancel") + _cancellationTokenSource?.Cancel(); else if (action == "restart-for-update") _updateService.RestartForUpdate(false); } - public async Task ShowNotification(string releaseId, string releaseVersion) + public void ShowNotification(string releaseId, string releaseVersion) { - new ToastContentBuilder() - .AddArgument("releaseId", releaseId) - .AddArgument("releaseVersion", releaseVersion) + GetBuilderForRelease(releaseId, releaseVersion) .AddText("Update available") .AddText($"Artemis version {releaseVersion} has been released") .AddButton(new ToastButton() @@ -89,9 +90,7 @@ public class WindowsUpdateNotificationProvider : IUpdateNotificationProvider ReleaseInstaller installer = _getReleaseInstaller(releaseId); void InstallerOnPropertyChanged(object? sender, PropertyChangedEventArgs e) => UpdateInstallProgress(releaseId, installer); - new ToastContentBuilder() - .AddArgument("releaseId", releaseId) - .AddArgument("releaseVersion", releaseVersion) + GetBuilderForRelease(releaseId, releaseVersion) .AddAudio(new ToastAudio {Silent = true}) .AddText("Installing Artemis update") .AddVisualChild(new AdaptiveProgressBar() @@ -104,19 +103,32 @@ public class WindowsUpdateNotificationProvider : IUpdateNotificationProvider .Show(t => { t.Tag = releaseId; - t.Data = GetInstallerNotificationData(installer); + t.Data = GetDataForInstaller(installer); }); + // Wait for Windows animations to catch up to us, we fast! await Task.Delay(2000); + _cancellationTokenSource = new CancellationTokenSource(); installer.PropertyChanged += InstallerOnPropertyChanged; - await installer.InstallAsync(CancellationToken.None); - installer.PropertyChanged -= InstallerOnPropertyChanged; + try + { + await installer.InstallAsync(_cancellationTokenSource.Token); + } + catch (Exception) + { + if (_cancellationTokenSource.IsCancellationRequested) + return; + throw; + } + finally + { + installer.PropertyChanged -= InstallerOnPropertyChanged; + } + // Queue an update in case the user interrupts the process after everything has been prepared _updateService.QueueUpdate(); - - new ToastContentBuilder() - .AddArgument("releaseId", releaseId) - .AddArgument("releaseVersion", releaseVersion) + + GetBuilderForRelease(releaseId, releaseVersion) .AddAudio(new ToastAudio {Silent = true}) .AddText("Update ready") .AddText($"Artemis version {releaseVersion} is ready to be applied") @@ -127,10 +139,15 @@ public class WindowsUpdateNotificationProvider : IUpdateNotificationProvider private void UpdateInstallProgress(string releaseId, ReleaseInstaller installer) { - ToastNotificationManagerCompat.CreateToastNotifier().Update(GetInstallerNotificationData(installer), releaseId); + ToastNotificationManagerCompat.CreateToastNotifier().Update(GetDataForInstaller(installer), releaseId); } - private NotificationData GetInstallerNotificationData(ReleaseInstaller installer) + private ToastContentBuilder GetBuilderForRelease(string releaseId, string releaseVersion) + { + return new ToastContentBuilder().AddArgument("releaseId", releaseId).AddArgument("releaseVersion", releaseVersion); + } + + private NotificationData GetDataForInstaller(ReleaseInstaller installer) { NotificationData data = new() { diff --git a/src/Artemis.UI/Screens/Settings/Updating/ReleaseViewModel.cs b/src/Artemis.UI/Screens/Settings/Updating/ReleaseViewModel.cs index bf965746a..ce00c716e 100644 --- a/src/Artemis.UI/Screens/Settings/Updating/ReleaseViewModel.cs +++ b/src/Artemis.UI/Screens/Settings/Updating/ReleaseViewModel.cs @@ -159,12 +159,10 @@ public class ReleaseViewModel : ActivatableViewModelBase _updateService.QueueUpdate(); InstallationFinished = true; } - catch (TaskCanceledException) - { - // ignored - } catch (Exception e) { + if (_installerCts.IsCancellationRequested) + return; _windowService.ShowExceptionDialog("Failed to install update", e); } finally diff --git a/src/Artemis.UI/Services/Updating/IUpdateNotificationProvider.cs b/src/Artemis.UI/Services/Updating/IUpdateNotificationProvider.cs index 0b7722609..9e1268f29 100644 --- a/src/Artemis.UI/Services/Updating/IUpdateNotificationProvider.cs +++ b/src/Artemis.UI/Services/Updating/IUpdateNotificationProvider.cs @@ -4,5 +4,5 @@ namespace Artemis.UI.Services.Updating; public interface IUpdateNotificationProvider { - Task ShowNotification(string releaseId, string releaseVersion); + void ShowNotification(string releaseId, string releaseVersion); } \ No newline at end of file diff --git a/src/Artemis.UI/Services/Updating/InAppUpdateNotificationProvider.cs b/src/Artemis.UI/Services/Updating/InAppUpdateNotificationProvider.cs index be08d2644..1a4d066b9 100644 --- a/src/Artemis.UI/Services/Updating/InAppUpdateNotificationProvider.cs +++ b/src/Artemis.UI/Services/Updating/InAppUpdateNotificationProvider.cs @@ -56,7 +56,7 @@ public class InAppUpdateNotificationProvider : IUpdateNotificationProvider } /// - public async Task ShowNotification(string releaseId, string releaseVersion) + public void ShowNotification(string releaseId, string releaseVersion) { if (_mainWindowService.IsMainWindowOpen) ShowInAppNotification(releaseId, releaseVersion); diff --git a/src/Artemis.UI/Services/Updating/UpdateService.cs b/src/Artemis.UI/Services/Updating/UpdateService.cs index 2b97df2de..14cb8f21e 100644 --- a/src/Artemis.UI/Services/Updating/UpdateService.cs +++ b/src/Artemis.UI/Services/Updating/UpdateService.cs @@ -84,9 +84,9 @@ public class UpdateService : IUpdateService Utilities.ApplyUpdate(false); } - private async Task ShowUpdateNotification(IGetNextRelease_NextPublishedRelease release) + private void ShowUpdateNotification(IGetNextRelease_NextPublishedRelease release) { - await _updateNotificationProvider.Value.ShowNotification(release.Id, release.Version); + _updateNotificationProvider.Value.ShowNotification(release.Id, release.Version); } private async Task AutoInstallUpdate(IGetNextRelease_NextPublishedRelease release) @@ -146,7 +146,7 @@ public class UpdateService : IUpdateService // If the window is open show the changelog, don't auto-update while the user is busy if (!_autoInstall.Value) - await ShowUpdateNotification(CachedLatestRelease); + ShowUpdateNotification(CachedLatestRelease); else await AutoInstallUpdate(CachedLatestRelease);