Xamarin.Essentials: MainThread

La clase MainThread permite que las aplicaciones ejecuten código en el subproceso de ejecución principal y determinen si un bloque de código determinado se ejecuta actualmente en el subproceso principal.

Fondo

La mayoría de los sistemas operativos, incluidos iOS, Android y Plataforma universal de Windows, usan un modelo de un único subproceso para el código que participa en 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 interfaz de usuario o el subproceso de UI. 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.

Algunas veces, las aplicaciones deben usar eventos que llamar al controlador de eventos en un subproceso de ejecución secundario. (Es posible que las clases Accelerometer, Compass, Gyroscope, Magnetometer y OrientationSensor de Xamarin.Essentials devuelvan información en un subproceso secundario cuando se usa con velocidades más rápidas). Si el controlador de eventos tiene que acceder a los elementos de la interfaz de usuario, debe ejecutar ese código en el subproceso principal. La clase MainThread permite que la aplicación ejecute este código en el subproceso principal.

Primeros pasos

Para empezar a usar esta API, lea la guía de introducción para Xamarin.Essentials con el fin de asegurarse de que la biblioteca está correctamente instalada y configurada en los proyectos.

Ejecución de código en el subproceso principal

Agregue una referencia a Xamarin.Essentials en la clase:

using Xamarin.Essentials;

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 que se debe ejecutar en el subproceso principal:

void MyMainThreadCode()
{
    // Code to run on the main thread
}

Luego, para ejecutar este método en el subproceso principal, haga referencia a él en el método BeginInvokeOnMainThread:

MainThread.BeginInvokeOnMainThread(MyMainThreadCode);

Nota:

Xamarin.Forms tiene un método denominado Device.BeginInvokeOnMainThread(Action) que hace lo mismo que MainThread.BeginInvokeOnMainThread(Action). Si bien puede usar cualquier método en una aplicación de Xamarin.Forms, considere si el código de llamada necesita una dependencia de Xamarin.Forms. Si no es así, MainThread.BeginInvokeOnMainThread(Action) probablemente sea una mejor opción.

Determinación de si el código se ejecuta en el subproceso principal

La clase MainThread también permite que una aplicación determine si un bloque de código determinado se ejecuta en el subproceso principal. La propiedad IsMainThread devuelve true si el código que llama a la propiedad se ejecuta en el subproceso principal. Un programa puede usar esta propiedad para ejecutar código diferente para el subproceso principal o secundario:

if (MainThread.IsMainThread)
{
    // Code to run if this is the main thread
}
else
{
    // Code to run if this is a secondary thread
}

Tal vez se pregunte si debe comprobar que el código se esté ejecutando en un subproceso secundario antes de llamar a BeginInvokeOnMainThread, por ejemplo, de esta manera:

if (MainThread.IsMainThread)
{
    MyMainThreadCode();
}
else
{
    MainThread.BeginInvokeOnMainThread(MyMainThreadCode);
}

Quizás sospeche que esta comprobación puede mejorar el rendimiento si el bloque de código ya se ejecuta en el subproceso principal.

Sin embargo, esta comprobación no es necesaria. Las implementaciones de plataforma de los BeginInvokeOnMainThread mismos comprueban si la llamada se realiza en el subproceso principal. La penalización de rendimiento si llama a BeginInvokeOnMainThread cuando no es realmente necesario es muy pequeña.

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.

API

Encuentre más vídeos de Xamarin en Channel 9 y YouTube.