Compartir a través de


Creación de un subproceso en el subproceso de interfaz de usuario de .NET MAUI

Browse sample.Examinar la muestra.

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.