---
name: managing-wpf-application-lifecycle
description: Manages WPF Application lifecycle including Startup, Exit, SessionEnding events and single instance detection. Use when handling app initialization, shutdown, or preventing multiple instances.
---
# WPF Application Lifecycle Patterns
Managing application startup, shutdown, and runtime behavior.
**Advanced Patterns:** See [ADVANCED.md](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
```xml
```
### 2.2 Override OnStartup
```csharp
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
```xml
```
### 3.2 Override OnExit
```csharp
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)
```csharp
// 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)
```csharp
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
```csharp
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
```csharp
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
}
```
---
## 6. References
- [Application Management Overview - Microsoft Docs](https://learn.microsoft.com/en-us/dotnet/desktop/wpf/app-development/application-management-overview)
- [Application Class - Microsoft Docs](https://learn.microsoft.com/en-us/dotnet/api/system.windows.application)
- [WPF Application Startup - Microsoft Docs](https://learn.microsoft.com/en-us/dotnet/desktop/wpf/app-development/building-a-wpf-application-wpf)