Xamarin.Essentials: MainThread

La classe MainThread permet aux applications d’exécuter du code sur le thread d’exécution principal, et de déterminer si un bloc de code donné est en cours d’exécution sur le thread principal.

Arrière-plan

La plupart des systèmes d’exploitation, notamment iOS, Android et la plateforme Windows universelle, utilisent un modèle monothread pour le code qui touche à l’interface utilisateur. Ce modèle est nécessaire pour sérialiser les événements de l’interface utilisateur, et en particulier les frappes et entrées tactiles. Ce thread est souvent appelé thread principal, thread d’interface utilisateur ou thread d’IU. Son inconvénient est que tout le code qui accède aux éléments d’interface utilisateur doit s’exécuter sur le thread principal de l’application.

Les applications ont parfois besoin d’utiliser des événements qui appellent le Gestionnaire d’événements sur un thread secondaire d’exécution. (Les Xamarin.Essentials classes Accelerometer, Compass, Gyroscope, Magnetometer, et OrientationSensor toutes peuvent retourner des informations sur un thread secondaire lorsqu’elles sont utilisées avec des vitesses plus rapides.) Si le gestionnaire d’événements doit accéder aux éléments de l’interface utilisateur, il doit exécuter ce code sur le thread main. La classe MainThread permet à l’application de se charger de cette exécution.

Bien démarrer

Pour commencer à utiliser cette API, lisez le guide de prise en main pour Xamarin.Essentials vous assurer que la bibliothèque est correctement installée et configurée dans vos projets.

Exécuter du code sur le thread principal

Ajoutez une référence à Xamarin.Essentials dans votre classe :

using Xamarin.Essentials;

Pour exécuter du code sur le thread principal, appelez la méthode statique MainThread.BeginInvokeOnMainThread. L’argument est un objet Action, qui consiste simplement en une méthode sans arguments ni valeur renvoyée :

MainThread.BeginInvokeOnMainThread(() =>
{
    // Code to run on the main thread
});

Il est également possible de définir une méthode distincte pour le code qui doit s’exécuter sur le thread principal :

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

Vous pouvez alors exécuter cette méthode sur le thread principal en y ajoutant une référence dans la méthode BeginInvokeOnMainThread :

MainThread.BeginInvokeOnMainThread(MyMainThreadCode);

Notes

Xamarin.Forms a une méthode appeléeDevice.BeginInvokeOnMainThread(Action) qui fait la même chose que MainThread.BeginInvokeOnMainThread(Action). Bien que vous puissiez utiliser l’une ou l’autre des méthodes dans une Xamarin.Forms application, déterminez si le code appelant a d’autres besoins pour une dépendance sur Xamarin.Forms. Si ce n’est pas le cas, MainThread.BeginInvokeOnMainThread(Action) est probablement une meilleure solution.

Déterminer si le code s’exécute sur le thread principal

La classe MainThread permet également à l’application déterminer si un bloc de code donné est en cours d’exécution sur le thread principal. La propriété IsMainThread retourne true si le code appelant la propriété s’exécute sur le thread principal. Un programme peut utiliser cette propriété pour exécuter un code différent pour le thread principal et un thread secondaire :

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

Vous vous demandez peut-être s’il faut vérifier si le code s’exécute sur un thread secondaire avant d’appeler BeginInvokeOnMainThread, par exemple ainsi :

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

On peut imaginer que cette vérification améliore les performances lorsque le bloc de code est déjà en cours d’exécution sur le thread principal.

Toutefois, elle n’est pas nécessaire. Les implémentations de BeginInvokeOnMainThread sur la plateforme vérifient directement si l’appel est effectué sur le thread principal. La perte de performances est très faible si l’on appelle BeginInvokeOnMainThread alors que ce n’est pas vraiment nécessaire.

Autres méthodes

La classe MainThread comprend les méthodes static supplémentaires suivantes qui peuvent être utilisées pour interagir avec des éléments d’interface utilisateur à partir de threads d’arrière-plan :

Méthode Arguments Retours Objectif
InvokeOnMainThreadAsync<T> Func<T> Task<T> Appelle un Func<T> sur le thread principal, puis attend qu’il se termine.
InvokeOnMainThreadAsync Action Task Appelle un Action sur le thread principal, puis attend qu’il se termine.
InvokeOnMainThreadAsync<T> Func<Task<T>> Task<T> Appelle un Func<Task<T>> sur le thread principal, puis attend qu’il se termine.
InvokeOnMainThreadAsync Func<Task> Task Appelle un Func<Task> sur le thread principal, puis attend qu’il se termine.
GetMainThreadSynchronizationContextAsync Task<SynchronizationContext> Retourne le SynchronizationContext pour le thread principal.

API

Retrouvez d’autres vidéos Xamarin sur Channel 9 et YouTube.