Creación de un subproceso en el subproceso de interfaz de usuario de .NET MAUI
En este artículo se describe cómo puedes usar la clase MainThread de .NET Multi-platform App UI (.NET MAUI) para ejecutar código en el subproceso principal de la interfaz de usuario. La mayoría de los sistemas operativos usan un modelo de subproceso único para el código que implica la interfaz de usuario. Este modelo resulta necesario para serializar de manera adecuada los eventos de la interfaz de usuario, incluidas pulsaciones de teclas y entradas táctiles. Con frecuencia, este subproceso se denomina el subproceso principal, el subproceso de la interfaz de usuario o el subproceso de IU. La desventaja que presenta este modelo es que todo el código que accede a los elementos de la interfaz de usuario se deben ejecutar en el subproceso principal de la aplicación.
La clase MainThread
está disponible en el espacio de nombres Microsoft.Maui.ApplicationModel
.
Cuándo es necesario
Algunas veces, las aplicaciones deben usar eventos que llaman al controlador de eventos en un subproceso secundario, como los sensores Accelerometer
o Compass
. Es posible que todos los sensores devuelvan información en un subproceso secundario cuando se usan con velocidades más rápidas. Si el controlador de eventos debe acceder a los elementos de la interfaz de usuario, debe invocar código en el subproceso principal.
Ejecución de código en el subproceso de la interfaz de usuario
Para ejecutar código en el subproceso principal, llame al método MainThread.BeginInvokeOnMainThread estático. El argumento es un objeto Action, que no es más que un método sin argumentos y sin valor devuelto:
MainThread.BeginInvokeOnMainThread(() =>
{
// Code to run on the main thread
});
También es posible definir un método independiente para el código y luego llamar a ese código con el método BeginInvokeOnMainThread
:
void MyMainThreadCode()
{
// Code to run on the main thread
}
MainThread.BeginInvokeOnMainThread(MyMainThreadCode);
Determinar si se requiere alguna invocación
Con la clase MainThread, puedes determinar si el código actual se ejecuta en el subproceso principal. La propiedad MainThread.IsMainThread devuelve true
si el código que llama a la propiedad se ejecuta en el subproceso principal, y false
si no lo hace. Es lógico suponer que necesitas determinar si el código se ejecuta en el subproceso principal antes de llamar a MainThread.BeginInvokeOnMainThread. Por ejemplo, el código siguiente usa IsMainThread
para detectar si se debe llamar al método MyMainThreadCode
directamente si el código se ejecuta en el subproceso principal. Si no se ejecuta en el subproceso principal, el método se pasa a BeginInvokeOnMainThread
:
if (MainThread.IsMainThread)
MyMainThreadCode();
else
MainThread.BeginInvokeOnMainThread(MyMainThreadCode);
Esta comprobación no es necesaria. El mismo BeginInvokeOnMainThread
comprueba si el código actual se ejecuta en el subproceso principal o no. Si el código se ejecuta en el subproceso principal, BeginInvokeOnMainThread
simplemente llama directamente al método proporcionado. Si el código se ejecuta en un subproceso secundario, BeginInvokeOnMainThread
invoca el método proporcionado en el subproceso principal. Por lo tanto, si el código que ejecutas es el mismo, independientemente del subproceso principal o secundario, simplemente llama a BeginInvokeOnMainThread
sin comprobar si es necesario. Hacer esto supone una sobrecarga insignificante.
La única razón por la que tendrías que comprobar la propiedad IsMainThread
es si tienes lógica de bifurcación que hace algo diferente en función del subproceso.
Otros métodos
La clase MainThread incluye los siguientes métodos static
adicionales, que se pueden usar para interactuar con los elementos de la interfaz de usuario de los subprocesos de fondo:
Método | Argumentos | Valores devueltos | Propósito |
---|---|---|---|
InvokeOnMainThreadAsync<T> |
Func<T> |
Task<T> |
Invoca un elemento Func<T> en el subproceso principal y espera a que se complete. |
InvokeOnMainThreadAsync |
Action |
Task |
Invoca un elemento Action en el subproceso principal y espera a que se complete. |
InvokeOnMainThreadAsync<T> |
Func<Task<T>> |
Task<T> |
Invoca un elemento Func<Task<T>> en el subproceso principal y espera a que se complete. |
InvokeOnMainThreadAsync |
Func<Task> |
Task |
Invoca un elemento Func<Task> en el subproceso principal y espera a que se complete. |
GetMainThreadSynchronizationContextAsync |
Task<SynchronizationContext> |
Devuelve el elemento SynchronizationContext para el subproceso principal. |