Xamarin.Essentials: MainThread

A classe MainThread permite que os aplicativos executem o código no thread de execução principal e determinem se certo bloco de código está sendo executado no thread principal.

Tela de fundo

A maioria dos sistemas operacionais, incluindo iOS, Android e a Plataforma Universal do Windows, usa um modelo de threading simples para o código que envolve a interface do usuário. Esse modelo é necessário para serializar adequadamente os eventos da interface do usuário, incluindo pressionamentos de tecla e entrada de toque. Este thread é frequentemente chamado de thread principal ou o thread da interface do usuário ou, ainda, o thread da IU. A desvantagem desse modelo é que todo código que acessa os elementos da interface do usuário deve ser executado no thread principal do aplicativo.

Às vezes, os aplicativos precisam usar eventos que chamam o manipulador de eventos em um thread de execução secundário. (As Xamarin.Essentials classes Accelerometer, Compass, Gyroscope, Magnetometere OrientationSensor podem retornar informações sobre um thread secundário quando usadas com velocidades mais rápidas.) Se o manipulador de eventos precisar acessar elementos de interface do usuário, ele deverá executar esse código no thread main. A classe MainThread permite que os aplicativos executem esse código no thread principal.

Introdução

Para começar a usar essa API, leia o guia de introdução para Xamarin.Essentials para garantir que a biblioteca esteja instalada e configurada corretamente em seus projetos.

Como executar códigos no Thread Principal

Adicione uma referência a Xamarin.Essentials em sua classe:

using Xamarin.Essentials;

Para executar o código no thread principal, chame o método MainThread.BeginInvokeOnMainThread estático. O argumento é um objeto Action, que é simplesmente um método sem argumentos e sem valor de retorno:

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

Também é possível definir um método separado para o código que deverá ser executado no thread principal:

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

Você pode executar esse método no thread principal fazendo referência a ele no método BeginInvokeOnMainThread:

MainThread.BeginInvokeOnMainThread(MyMainThreadCode);

Observação

Xamarin.Forms tem um método chamadoDevice.BeginInvokeOnMainThread(Action) que faz a mesma coisa que MainThread.BeginInvokeOnMainThread(Action). Embora você possa usar qualquer método em um Xamarin.Forms aplicativo, considere se o código de chamada tem ou não qualquer outra necessidade de uma dependência em Xamarin.Forms. Caso contrário, é provável que MainThread.BeginInvokeOnMainThread(Action) seja uma opção melhor.

Como determinar se o código está em execução no thread principal

A classe MainThread também permite que um aplicativo determine se certo bloco de código está em execução no thread principal. A propriedade IsMainThread retorna true se o código que chama a propriedade estiver em execução no thread principal. Um programa pode usar essa propriedade para executar um código diferente no thread principal ou em um thread secundário:

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

Você pode se perguntar se deve verificar se o código está sendo executado em um thread secundário antes de chamar BeginInvokeOnMainThread, por exemplo:

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

Você pode suspeitar que essa verificação possa melhorar o desempenho se o bloco de código já estiver em execução no thread principal.

No entanto, essa verificação não é necessária. As implementações da plataforma de BeginInvokeOnMainThread verificam se a chamada é feita no thread principal. A perda de desempenho é pouca se você chamar BeginInvokeOnMainThread quando não for realmente necessário.

Métodos adicionais

A classe MainThread inclui os seguintes métodos static adicionais que podem ser usados para interagir com elementos da interface do usuário dos threads em segundo plano:

Método Argumentos Retornos Finalidade
InvokeOnMainThreadAsync<T> Func<T> Task<T> Invoca um Func<T> no thread principal e aguarda sua conclusão.
InvokeOnMainThreadAsync Action Task Invoca um Action no thread principal e aguarda sua conclusão.
InvokeOnMainThreadAsync<T> Func<Task<T>> Task<T> Invoca um Func<Task<T>> no thread principal e aguarda sua conclusão.
InvokeOnMainThreadAsync Func<Task> Task Invoca um Func<Task> no thread principal e aguarda sua conclusão.
GetMainThreadSynchronizationContextAsync Task<SynchronizationContext> Retorna o SynchronizationContext para o thread principal.

API

Encontre mais vídeos sobre o Xamarin no Channel 9 e no YouTube.