Desktop beendet sich auf SIGTERM, statt bis zum SIGKILL weiterzulaufen
#600: Die ConsoleLifetime des Hosts faengt SIGTERM ab und ruft StopApplication. Die Avalonia-Oberflaeche hing nicht daran - Main wartete weiter auf sie, und systemctl stop, Abmelden oder Herunterfahren endeten mit SIGKILL. App.axaml.cs haengt AvaloniaUiHost.ShutdownFromHost an ApplicationStopping: Die Oberflaeche schliesst sich ohne Sicherheitsabfrage (der Stopp von aussen ist selbst die Anweisung), danach laeuft der geordnete Dienst-Stopp aus Program.Main. Auf der Linux-VM geprueft: SIGTERM -> beendet nach 1 s, "Dienste in 0,1 s beendet"; Gegenprobe "Beenden" in der Oberflaeche ebenso. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -2,7 +2,9 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls.ApplicationLifetimes;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Avalonia.Threading;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using PolyTrader.App.Avalonia.Shell;
|
||||
using PolyTrader.App.Avalonia.Views;
|
||||
|
||||
@@ -50,6 +52,17 @@ namespace PolyTrader.App.Avalonia
|
||||
// Schliessen der Shell laeuft ueber die Sicherheitsabfrage (wie bisher das X).
|
||||
desktop.ShutdownMode = global::Avalonia.Controls.ShutdownMode.OnMainWindowClose;
|
||||
|
||||
// Stopp von aussen (SIGTERM, systemctl stop, Abmelden): Die ConsoleLifetime des Hosts faengt das
|
||||
// Signal ab und ruft StopApplication - die Oberflaeche hing daran bisher nicht, Main wartete weiter
|
||||
// auf sie, und der Prozess endete erst mit SIGKILL. Jetzt schliesst sie sich, danach laeuft der
|
||||
// geordnete Stopp in Program.Main. Beim eigenen "Beenden" feuert ApplicationStopping erst, wenn die
|
||||
// Oberflaeche schon zu ist; der Aufruf findet dann ShutdownConfirmed gesetzt vor.
|
||||
Services.GetService<IHostApplicationLifetime>()?.ApplicationStopping.Register(() =>
|
||||
{
|
||||
try { Dispatcher.UIThread.Post(uiHost.ShutdownFromHost); }
|
||||
catch { /* Dispatcher schon beendet - dann ist die Oberflaeche ohnehin zu */ }
|
||||
});
|
||||
|
||||
// Erste Seite: die Startseite (frühere LauncherForm).
|
||||
uiHost.ActivateMain();
|
||||
}
|
||||
|
||||
@@ -102,6 +102,23 @@ namespace PolyTrader.App.Avalonia.Shell
|
||||
/// </summary>
|
||||
public void RequestShutdown() => RequestShutdown(onConfirmed: null);
|
||||
|
||||
/// <summary>
|
||||
/// Schließt die Oberfläche OHNE Sicherheitsabfrage – nur für einen Stopp von außen (SIGTERM, systemctl
|
||||
/// stop, Abmelden, Herunterfahren). Der ist selbst schon die ausdrückliche Anweisung; eine Abfrage, die
|
||||
/// niemand beantwortet, hielt den Prozess bis zum SIGKILL am Leben. Nach dem Schließen läuft derselbe
|
||||
/// geordnete Stopp der Dienste wie bei „Beenden" (Program.Main). Muss auf dem UI-Thread laufen.
|
||||
/// </summary>
|
||||
public void ShutdownFromHost()
|
||||
{
|
||||
if (ShutdownConfirmed) return;
|
||||
ShutdownConfirmed = true;
|
||||
if (global::Avalonia.Application.Current?.ApplicationLifetime
|
||||
is global::Avalonia.Controls.ApplicationLifetimes.IClassicDesktopStyleApplicationLifetime desktop)
|
||||
{
|
||||
desktop.Shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wie <see cref="RequestShutdown()"/>, mit einem Schritt zwischen Bestätigung und Herunterfahren.
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user