Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
En una aplicación de SDK de Aplicaciones para Windows de escritorio, el proceso continúa ejecutándose hasta que el usuario lo cierra explícitamente. Las aplicaciones de escritorio no pasan por el ciclo de vida de suspensión, reanudación y finalización automáticas que usan las aplicaciones para UWP. Esto le proporciona más control, pero también más responsabilidad para administrar el estado.
Prerequisites
- Un proyecto de escritorio de SDK de Aplicaciones para Windows. Para conocer los pasos de configuración, consulte Creación de la primera aplicación winUI 3.
- Familiaridad con la
Microsoft.UI.Windowing.AppWindowclase y, para aplicaciones empaquetadas,Windows.Storage.ApplicationData.
Importante
Las aplicaciones de SDK de Aplicaciones para Windows de escritorio no se suspenden y reanudan automáticamente como las aplicaciones para UWP. La aplicación se ejecuta continuamente hasta que el usuario o el sistema lo apagan. Todavía debe implementar buenas prácticas de administración de estado para controlar apagados inesperados, reinicios del sistema y pérdida de energía.
¿Por qué es importante la administración de estados?
Aunque el sistema operativo no suspenda las aplicaciones de escritorio, todavía hay situaciones en las que la aplicación puede perder el estado no guardado:
- El usuario cierra la aplicación mientras el trabajo está en curso
- El sistema se reinicia para una actualización.
- La pérdida de energía o un bloqueo finaliza el proceso
- El usuario cierra sesión de Windows
Diseñe la aplicación para controlar estos casos correctamente guardando el estado importante con frecuencia y restablezándolo cuando se inicia la aplicación.
Guardar el estado incrementalmente
En lugar de guardar todo el estado en el apagado, guarde el estado incrementalmente a medida que el usuario funcione. Esto reduce el riesgo de pérdida de datos y distribuye el costo de E/S en toda la duración de la aplicación.
private async void OnThemeChanged(object sender, SelectionChangedEventArgs e)
{
var selectedTheme = (sender as ComboBox)?.SelectedItem?.ToString();
if (selectedTheme != null)
{
await SaveSettingAsync("AppTheme", selectedTheme);
}
}
private async Task SaveSettingAsync(string key, string value)
{
// Use local file storage, a database, or ApplicationData for packaged apps.
var localFolder = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
var settingsDir = System.IO.Path.Combine(localFolder, "MyApp");
Directory.CreateDirectory(settingsDir);
var settingsPath = System.IO.Path.Combine(settingsDir, "settings.json");
// Read existing settings, update, and save asynchronously.
var settings = LoadSettings(settingsPath);
settings[key] = value;
await File.WriteAllTextAsync(settingsPath, System.Text.Json.JsonSerializer.Serialize(settings));
}
private Dictionary<string, string> LoadSettings(string path)
{
// Read and deserialize the settings file, or return an empty set if it doesn't exist yet.
if (!File.Exists(path))
{
return new Dictionary<string, string>();
}
var json = File.ReadAllText(path);
return System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, string>>(json)
?? new Dictionary<string, string>();
}
Uso de ApplicationData para aplicaciones empaquetadas
Si la aplicación se empaqueta con MSIX, puedes usar Windows.Storage.ApplicationData.Current.LocalSettings para almacenar configuraciones pequeñas y LocalFolder para datos más grandes. El sistema administra estas ubicaciones y se limpia cuando se desinstala la aplicación.
Note
ApplicationData.Current requiere la identidad del paquete. Si la aplicación está desempaquetada, use Environment.SpecialFolder.LocalApplicationData u otra ubicación de archivo estándar en su lugar.
// For packaged apps with package identity:
string filePath = "C:\\Users\\Example\\Documents\\report.docx";
var localSettings = Windows.Storage.ApplicationData.Current.LocalSettings;
localSettings.Values["LastOpenedFile"] = filePath;
Restaurar el estado al iniciar
Cuando se inicie la aplicación, compruebe el estado guardado anteriormente y restáurelo. Esto proporciona al usuario una experiencia fluida: puede retomar donde lo dejó.
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
// Restore the last opened file, if any.
var localSettings = Windows.Storage.ApplicationData.Current.LocalSettings;
if (localSettings.Values.TryGetValue("LastOpenedFile", out var path))
{
OpenFile(path.ToString());
}
}
private void OpenFile(string path)
{
// Load the document at the given path and update the UI.
}
Control del evento AppWindow.Closing
Use el Closing evento en Microsoft.UI.Windowing.AppWindow para guardar el estado crítico antes de que finalice la aplicación. Esta es la última oportunidad de conservar el estado cuando el usuario cierra la ventana.
Importante
En WinUI 3, el Window.Closed evento no admite la cancelación. Para pedir confirmación al usuario antes de cerrar (por ejemplo, para guardar los cambios no guardados), use en su lugar el evento Microsoft.UI.Windowing.AppWindow.Closing, que proporciona un objeto AppWindowClosingEventArgs con una propiedad Cancel.
// In your Window constructor or initialization code:
var appWindow = this.AppWindow;
appWindow.Closing += AppWindow_Closing;
void AppWindow_Closing(AppWindow sender, AppWindowClosingEventArgs args)
{
// See the following examples for what to do here.
}
private void AppWindow_Closing(AppWindow sender, AppWindowClosingEventArgs args)
{
SaveCurrentDocument();
SaveWindowPosition();
}
private void SaveCurrentDocument()
{
// Persist the current document to disk.
}
private void SaveWindowPosition()
{
// Persist the window's current size and position.
}
Para pedir confirmación al usuario antes de cerrar la ventana, establezca args.Cancel = true para evitar que la ventana se cierre y, a continuación, ciérrela mediante programación después de que el usuario lo confirme. Utilice un indicador de guarda para evitar la reentrada, ya que llamar a this.Close() vuelve a activar el evento Closing:
private bool _isClosing = false;
private bool HasUnsavedChanges { get; set; }
private async void AppWindow_Closing(AppWindow sender, AppWindowClosingEventArgs args)
{
if (_isClosing) return;
if (HasUnsavedChanges)
{
args.Cancel = true; // Prevent the window from closing.
// ShowSaveDialog returns true if the user chose to save.
var shouldSave = await ShowSaveDialog();
if (shouldSave)
{
await SaveCurrentDocumentAsync();
}
// Set the guard flag before closing to prevent re-entrancy.
_isClosing = true;
this.Close();
}
}
private Task<bool> ShowSaveDialog()
{
// Prompt the user to save, discard, or cancel.
return Task.FromResult(true);
}
private Task SaveCurrentDocumentAsync()
{
// Persist the current document to disk asynchronously.
return Task.CompletedTask;
}
Prácticas recomendadas
| Práctica | Instrucciones |
|---|---|
| Guardar con frecuencia | No espere al apagado — guarde el estado mientras el usuario trabaja |
| Uso de E/S asincrónica | Uso FileStream con useAsync: true o File.WriteAllTextAsync para evitar el bloqueo de la interfaz de usuario |
| Minimizar el tamaño del estado | Guarde solo los datos que necesita para restaurar la posición del usuario. |
| Controlar eventos de energía | Detecta PowerManager.EnergySaverStatusChanged para adaptar el comportamiento |
| Comprobar los apagados inesperados | Usar el Administrador de tareas para finalizar la aplicación y comprobar la recuperación de estado |