From 1829dcb064b36b46d09a16c75c677d493a19fcc9 Mon Sep 17 00:00:00 2001 From: Max Katz Date: Fri, 19 Apr 2024 17:16:54 -0700 Subject: [PATCH] Fix app shutdown cancellation via window (#15438) * Don't call dispatcher shutdown, when app shutdown was cancelled * Assert Dispatcher.UIThread.ShutdownStarted in TryShutdown_Cancellable_By_Preventing_Window_Close --- .../ClassicDesktopStyleApplicationLifetime.cs | 12 +++++++++--- .../DesktopStyleApplicationLifetimeTests.cs | 11 ++++++++--- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/Avalonia.Controls/ApplicationLifetimes/ClassicDesktopStyleApplicationLifetime.cs b/src/Avalonia.Controls/ApplicationLifetimes/ClassicDesktopStyleApplicationLifetime.cs index 497be9d671..43c140a05f 100644 --- a/src/Avalonia.Controls/ApplicationLifetimes/ClassicDesktopStyleApplicationLifetime.cs +++ b/src/Avalonia.Controls/ApplicationLifetimes/ClassicDesktopStyleApplicationLifetime.cs @@ -163,6 +163,7 @@ namespace Avalonia.Controls.ApplicationLifetimes _exitCode = exitCode; _isShuttingDown = true; + var shutdownCancelled = false; try { @@ -180,6 +181,7 @@ namespace Avalonia.Controls.ApplicationLifetimes if (!force && Windows.Count > 0) { e.Cancel = true; + shutdownCancelled = true; return false; } @@ -189,10 +191,14 @@ namespace Avalonia.Controls.ApplicationLifetimes } finally { - _cts?.Cancel(); - _cts = null; _isShuttingDown = false; - Dispatcher.UIThread.InvokeShutdown(); + + if (!shutdownCancelled) + { + _cts?.Cancel(); + _cts = null; + Dispatcher.UIThread.InvokeShutdown(); + } } return true; diff --git a/tests/Avalonia.Controls.UnitTests/DesktopStyleApplicationLifetimeTests.cs b/tests/Avalonia.Controls.UnitTests/DesktopStyleApplicationLifetimeTests.cs index 73571b4f5b..ec0fc46fc7 100644 --- a/tests/Avalonia.Controls.UnitTests/DesktopStyleApplicationLifetimeTests.cs +++ b/tests/Avalonia.Controls.UnitTests/DesktopStyleApplicationLifetimeTests.cs @@ -355,9 +355,13 @@ namespace Avalonia.Controls.UnitTests { lifetime.SetupCore(Array.Empty()); - var hasExit = false; + lifetime.Exit += (_, _) => Assert.Fail("lifetime.Exit was called."); + Dispatcher.UIThread.ShutdownStarted += UiThreadOnShutdownStarted; - lifetime.Exit += (_, _) => hasExit = true; + static void UiThreadOnShutdownStarted(object sender, EventArgs e) + { + Assert.Fail("Dispatcher.UIThread.ShutdownStarted was called."); + } var windowA = new Window(); @@ -378,7 +382,8 @@ namespace Avalonia.Controls.UnitTests lifetime.TryShutdown(); Assert.Equal(1, raised); - Assert.False(hasExit); + + Dispatcher.UIThread.ShutdownStarted -= UiThreadOnShutdownStarted; } }