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.
Los usuarios esperan que la aplicación siga respondiendo mientras realiza el cálculo, independientemente del tipo de máquina. Esto significa diferentes cosas para diferentes aplicaciones: proporcionar física realista, cargar datos desde el disco o la web, presentar escenas complejas, navegar entre páginas o procesar datos. Independientemente del tipo de cálculo, los usuarios quieren que la aplicación actúe en su entrada y elimine las instancias en las que parezca que no responde.
La aplicación está controlada por eventos: el código realiza el trabajo en respuesta a un evento y, a continuación, se coloca inactivo hasta el siguiente evento. El código de la plataforma para la interfaz de usuario (diseño, entrada, generación de eventos) y el código de la aplicación para la interfaz de usuario se ejecutan en el mismo subproceso de interfaz de usuario. Solo una instrucción se ejecuta en ese subproceso a la vez, por lo que si el código de la aplicación tarda demasiado tiempo en procesar un evento, el marco no puede ejecutar el diseño ni generar nuevos eventos. La capacidad de respuesta de tu aplicación está relacionada con la disponibilidad del hilo de la interfaz de usuario para procesar tareas.
Debe usar el hilo de la interfaz de usuario para realizar casi todos los cambios en los elementos de la interfaz de usuario. No puede actualizar la interfaz de usuario desde un subproceso en segundo plano, pero puede publicar un mensaje en ella con DispatcherQueue.TryEnqueue para hacer que el código se ejecute allí.
Importante
En las aplicaciones de escritorio de WinUI 3, use DispatcherQueue en lugar de UWP CoreDispatcher. Acceda a la cola de distribución a través de la propiedad DispatcherQueue de la ventana o DispatcherQueue.GetForCurrentThread().
Note
Un subproceso de representación independiente puede aplicar cambios de interfaz de usuario que no afectan a cómo se controla la entrada o el diseño básico. Por ejemplo, muchas animaciones y transiciones que no afectan al diseño se pueden ejecutar en este subproceso de representación.
Retrasar la creación de instancias del elemento
Algunas de las fases más lentas de una aplicación incluyen el inicio y el cambio de vistas. No haga más trabajo de lo necesario para abrir la interfaz de usuario que ve inicialmente el usuario. Por ejemplo, no cree la interfaz de usuario para contenido o contenido emergente divulgado progresivamente.
- Use el atributo x:Load para crear instancias de los elementos de forma diferida.
- Inserte elementos mediante programación en el árbol a petición.
Use DispatcherQueue.TryEnqueue con una prioridad baja para poner trabajo en cola para que el subproceso de interfaz de usuario lo procese cuando no esté ocupado.
Usar API asincrónicas
Para mantener la capacidad de respuesta de la aplicación, use las versiones asincrónicas de las API cuando estén disponibles. Una API asincrónica garantiza que el subproceso de ejecución activo nunca se bloquee durante un período de tiempo significativo. Al llamar a una API desde el subproceso de la interfaz de usuario, use siempre la versión asincrónica si existe.
Delega el trabajo a subprocesos en segundo plano
Escriba controladores de eventos para que se devuelvan rápidamente. Cuando es necesario realizar una cantidad de trabajo no trivial, programela en un subproceso en segundo plano y devuelva.
Puede programar el trabajo de forma asincrónica mediante el await operador en C#. Sin embargo, await no garantiza que el trabajo se ejecute en un subproceso en segundo plano. Muchas API del SDK de aplicaciones de Windows programan tareas en un subproceso en segundo plano, pero si llamas al código de la aplicación únicamente mediante await, ejecutas el método en el subproceso de la interfaz de usuario. Debe ejecutar explícitamente el código de su aplicación en un hilo en segundo plano. En C#, para ello, pase código a Task.Run.
Recuerde que solo puede acceder a los elementos de la interfaz de usuario desde el hilo de la interfaz de usuario. Use el hilo de la interfaz de usuario para acceder a los elementos de la interfaz de usuario antes de iniciar una tarea en segundo plano, o use DispatcherQueue.TryEnqueue en el hilo en segundo plano para enviar las actualizaciones de la interfaz de usuario al hilo de la interfaz de usuario.
public sealed partial class MainWindow : Window
{
// Declared in MainWindow.xaml as x:Name="statusText".
private TextBlock statusText;
private async void NextMove_Click(object sender, RoutedEventArgs e)
{
// The await causes the handler to return immediately.
await Task.Run(() => ComputeNextMove());
// Now update the UI with the results.
// This code runs on the UI thread after ComputeNextMove completes.
statusText.Text = "Move computed.";
}
private void ComputeNextMove()
{
// Perform background work here.
// Don't directly access UI elements from this method.
}
}
En este ejemplo, el controlador NextMove_Click retorna en await para mantener la capacidad de respuesta del hilo de la interfaz de usuario. La ejecución se reanuda en ese controlador después de que ComputeNextMove (que se ejecuta en un subproceso en segundo plano) se complete, y el código restante actualiza la interfaz de usuario con los resultados.