Compartilhar via


Publicar e assinar mensagens

O padrão de publicação-assinatura é um padrão de mensagens no qual os editores enviam mensagens sem ter conhecimento de nenhum receptor, conhecidos como assinantes. Da mesma forma, os assinantes escutam mensagens específicas, sem ter conhecimento de nenhum editor.

Os eventos no .NET implementam o padrão publicador-assinante e são a forma mais simples de uma camada de comunicação entre componentes quando o acoplamento frouxo não é necessário, como entre um controle e a página que o contém. No entanto, os tempos de vida do editor e do assinante são acoplados por referências de objeto entre si e o tipo de assinante deve ter uma referência ao tipo de publicador. Isso pode criar problemas de gerenciamento de memória, especialmente quando há objetos de curta duração que assinam um evento de um objeto estático ou de longa duração. Se o manipulador de eventos não for removido, o assinante será mantido ativo pela referência a ele no publicador e isso impedirá ou atrasará a coleta de lixo do assinante.

A classe MessagingCenter da interface do usuário de aplicativo multiplataforma do .NET (.NET MAUI) implementa o padrão de publicação-assinatura, permitindo a comunicação baseada em mensagens entre componentes que são difíceis de conectar por referências de objeto e tipo. Esse mecanismo permite que editores e assinantes se comuniquem sem ter uma referência uns aos outros, ajudando a reduzir as dependências entre eles.

Importante

MessagingCenter foi preterido e recomendamos substituí-lo por WeakReferenceMessenger no pacote CommunityToolkit.Mvvm NuGet. Para obter mais informações, consulte Messenger.

A classe MessagingCenter fornece funcionalidade de publicação/assinatura multicast. Isso significa que pode haver vários editores que publicam uma única mensagem e pode haver vários assinantes escutando a mesma mensagem:

funcionalidade de publicação/assinatura multicast.

Os editores enviam mensagens usando o método MessagingCenter.Send, enquanto os assinantes escutam mensagens usando o método MessagingCenter.Subscribe. Além disso, os assinantes também podem cancelar a assinatura de mensagens, se necessário, com o método MessagingCenter.Unsubscribe.

Importante

Internamente, a classe MessagingCenter usa referências fracas. Isso significa que ele não manterá os objetos vivos e permitirá que eles sejam coletados pelo coletor de lixo. Portanto, só deve ser necessário cancelar a assinatura de uma mensagem quando uma classe não quiser mais receber a mensagem.

Publicar uma mensagem

MessagingCenter mensagens são cadeias de caracteres. Os editores notificam os assinantes de uma mensagem com uma das sobrecargas de MessagingCenter.Send. O exemplo de código a seguir publica uma mensagem de Hi:

MessagingCenter.Send<MainPage>(this, "Hi");

Neste exemplo, o método Send especifica um argumento genérico que representa o remetente. Para receber a mensagem, um assinante também deve especificar o mesmo argumento genérico, indicando que está escutando uma mensagem desse remetente. Além disso, este exemplo especifica dois argumentos de método:

  • O primeiro argumento especifica a instância do remetente.
  • O segundo argumento especifica a mensagem.

Os dados da carga útil também podem ser enviados com uma mensagem.

MessagingCenter.Send<MainPage, string>(this, "Hi", "John");

Neste exemplo, o método Send especifica dois argumentos genéricos. O primeiro é o tipo que envia a mensagem, e o segundo é o tipo de dados de carga útil que estão sendo enviados. Para receber a mensagem, um assinante também deve especificar os mesmos argumentos genéricos. Isso permite que várias mensagens que compartilham uma identidade de mensagem, mas que enviam diferentes tipos de dados de conteúdo, sejam recebidas por assinantes diferentes. Além disso, este exemplo especifica um terceiro argumento de método que representa os dados de conteúdo a serem enviados ao assinante. Nesse caso, os dados de carga útil são um string.

O método Send publicará a mensagem e todos os dados de conteúdo usando uma abordagem de fogo e esquecer. Portanto, a mensagem é enviada mesmo se não houver assinantes registrados para receber a mensagem. Nessa situação, a mensagem enviada é ignorada.

Assinar uma mensagem

Os assinantes podem se registrar para receber uma mensagem usando uma das sobrecargas de MessagingCenter.Subscribe. O exemplo de código a seguir mostra um exemplo disso:

MessagingCenter.Subscribe<MainPage> (this, "Hi", (sender) =>
{
    // Do something whenever the "Hi" message is received
});

Neste exemplo, o método Subscribe inscreve o objeto this às mensagens Hi enviadas pelo tipo MainPage e executa um callback em resposta ao recebimento da mensagem. O delegado de retorno de chamada, especificado como uma expressão lambda, pode ser um código que atualiza a interface do usuário, salva alguns dados ou dispara alguma outra operação.

Nota

Talvez um assinante não precise lidar com todas as instâncias de uma mensagem publicada, e isso pode ser controlado pelos argumentos de tipo genérico especificados no método Subscribe.

O exemplo a seguir mostra como assinar uma mensagem que contém dados de conteúdo:

MessagingCenter.Subscribe<MainPage, string>(this, "Hi", async (sender, arg) =>
{
    await DisplayAlert("Message received", "arg=" + arg, "OK");
});

Neste exemplo, o método Subscribe inscreve-se em mensagens Hi enviadas pelo tipo MainPage, cuja carga útil de dados é um string. Um delegado de retorno de chamada é executado em resposta ao recebimento dessa mensagem, exibindo os dados de carga em um alerta.

Importante

O delegado executado pelo método Subscribe será executado no mesmo thread em que a mensagem é publicada usando o método Send.

Cancelar a assinatura de uma mensagem

Os assinantes podem cancelar a assinatura de mensagens que não desejam mais receber. Isso é feito com uma das sobrecargas de MessagingCenter.Unsubscribe:

MessagingCenter.Unsubscribe<MainPage>(this, "Hi");

Neste exemplo, o método Unsubscribe cancela a assinatura do objeto this da mensagem Hi enviada pelo tipo MainPage.

As mensagens que contêm dados de carga devem ser canceladas utilizando a sobrecarga Unsubscribe que especifica dois argumentos genéricos:

MessagingCenter.Unsubscribe<MainPage, string>(this, "Hi");

Neste exemplo, o método Unsubscribe cancela a assinatura do objeto this da mensagem Hi enviada pelo tipo MainPage, cujos dados de conteúdo são um string.