managing-wpf-application-lifecycle
0
总安装量
1
周安装量
安装命令
npx skills add https://github.com/christian289/dotnet-with-claudecode --skill managing-wpf-application-lifecycle
Agent 安装分布
amp
1
cline
1
opencode
1
cursor
1
continue
1
kimi-cli
1
Skill 文档
WPF Application Lifecycle Patterns
Managing application startup, shutdown, and runtime behavior.
Advanced Patterns: See ADVANCED.md for single instance, settings, and activation handling.
1. Application Lifecycle Overview
Application Start
â
ââ App Constructor
ââ App.OnStartup() / Startup event
ââ MainWindow Constructor
ââ MainWindow.Loaded event
â
â¼
Running State
â
ââ Activated / Deactivated events
ââ SessionEnding event (logoff/shutdown)
â
â¼
Shutdown Initiated
â
ââ Window.Closing event (can cancel)
ââ Window.Closed event
ââ App.OnExit() / Exit event
â
â¼
Application End
2. Startup Handling
2.1 App.xaml Startup
<Application x:Class="MyApp.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml"
Startup="Application_Startup"
Exit="Application_Exit"
SessionEnding="Application_SessionEnding">
<Application.Resources>
<!-- Resources -->
</Application.Resources>
</Application>
2.2 Override OnStartup
namespace MyApp;
using System.Windows;
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
// Process command line arguments
ProcessCommandLineArgs(e.Args);
// Initialize services
InitializeServices();
// Create and show main window manually (if StartupUri not set)
var mainWindow = new MainWindow();
mainWindow.Show();
}
private void ProcessCommandLineArgs(string[] args)
{
foreach (var arg in args)
{
if (arg.Equals("--debug", StringComparison.OrdinalIgnoreCase))
{
// Enable debug mode
}
else if (arg.StartsWith("--file=", StringComparison.OrdinalIgnoreCase))
{
var filePath = arg[7..];
// Process file
}
}
}
private void InitializeServices()
{
// DI container setup, logging, etc.
}
}
3. Shutdown Handling
3.1 ShutdownMode
<!-- Default: When last window closes -->
<Application ShutdownMode="OnLastWindowClose">
<!-- When main window closes -->
<Application ShutdownMode="OnMainWindowClose">
<!-- Only when Shutdown() is called explicitly -->
<Application ShutdownMode="OnExplicitShutdown">
3.2 Override OnExit
protected override void OnExit(ExitEventArgs e)
{
// Save settings
SaveUserSettings();
// Cleanup resources
DisposeServices();
// Set exit code
e.ApplicationExitCode = 0;
base.OnExit(e);
}
3.3 Window Closing (Can Cancel)
// MainWindow.xaml.cs
private void Window_Closing(object sender, CancelEventArgs e)
{
// Check for unsaved changes
if (HasUnsavedChanges)
{
var result = MessageBox.Show(
"You have unsaved changes. Do you want to save before closing?",
"Unsaved Changes",
MessageBoxButton.YesNoCancel,
MessageBoxImage.Warning);
switch (result)
{
case MessageBoxResult.Yes:
SaveChanges();
break;
case MessageBoxResult.Cancel:
e.Cancel = true; // Prevent closing
return;
}
}
}
4. Session Ending (Logoff/Shutdown)
private void Application_SessionEnding(object sender, SessionEndingCancelEventArgs e)
{
// e.ReasonSessionEnding: Logoff or Shutdown
if (HasCriticalOperation)
{
var result = MessageBox.Show(
"A critical operation is in progress. Are you sure you want to close?",
"Session Ending",
MessageBoxButton.YesNo,
MessageBoxImage.Warning);
if (result == MessageBoxResult.No)
{
e.Cancel = true; // Try to prevent session end
return;
}
}
// Perform emergency save
EmergencySave();
}
5. Unhandled Exception Handling
5.1 UI Thread Exceptions
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
// Handle UI thread exceptions
DispatcherUnhandledException += OnDispatcherUnhandledException;
}
private void OnDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
{
// Log the exception
LogException(e.Exception);
// Show error dialog
MessageBox.Show(
$"An unexpected error occurred:\n{e.Exception.Message}",
"Error",
MessageBoxButton.OK,
MessageBoxImage.Error);
// Prevent application crash (handle the exception)
e.Handled = true;
}
}
5.2 Background Thread Exceptions
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
// Handle non-UI thread exceptions
AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;
// Handle Task exceptions
TaskScheduler.UnobservedTaskException += OnUnobservedTaskException;
}
private void OnUnhandledException(object sender, UnhandledExceptionEventArgs e)
{
var exception = e.ExceptionObject as Exception;
LogException(exception);
if (e.IsTerminating)
{
EmergencySave();
}
}
private void OnUnobservedTaskException(object? sender, UnobservedTaskExceptionEventArgs e)
{
LogException(e.Exception);
e.SetObserved(); // Prevent crash
}