Compartir a través de


Publicación y suscripción a mensajes

El patrón publish-subscribe es un patrón de mensajería en el que los publicadores envían mensajes sin tener conocimiento de los receptores, conocidos como suscriptores. Del mismo modo, los suscriptores escuchan mensajes específicos, sin tener conocimiento de ningún publicador.

Los eventos de .NET implementan el patrón publish-subscribe y son el enfoque más sencillo y sencillo para una capa de comunicación entre componentes si no se requiere acoplamiento flexible, como un control y la página que lo contiene. Sin embargo, las vidas del publicador y del suscriptor están interrelacionadas a través de referencias de objeto mutuas, y el tipo de suscriptor debe tener una referencia al tipo de publicador. Esto puede crear problemas de administración de memoria, especialmente cuando hay objetos de corta duración que se suscriben a un evento de un objeto estático o de larga duración. Si el controlador de eventos no se quita, el suscriptor se mantendrá activo por la referencia a él en el publicador y esto impedirá o retrasará la recolección de basura del suscriptor.

La clase MessagingCenter de la interfaz de usuario de aplicación multiplataforma de .NET (.NET MAUI) implementa el patrón publish-subscribe, permitiendo la comunicación basada en mensajes entre componentes que no son convenientes para vincular por referencias de objeto y tipo. Este mecanismo permite a los publicadores y suscriptores comunicarse sin tener una referencia entre sí, lo que ayuda a reducir las dependencias entre ellos.

Importante

MessagingCenter ha quedado en desuso y se recomienda reemplazarlo por WeakReferenceMessenger en el paquete NuGet CommunityToolkit.Mvvm. Para obtener más información, consulta Messenger.

La clase MessagingCenter proporciona funcionalidad de difusión múltiple para publicación y suscripción. Esto significa que puede haber varios publicadores que publiquen un único mensaje y que haya varios suscriptores escuchando el mismo mensaje:

funcionalidad de publicación y suscripción de multidifusión.

Los publicadores envían mensajes mediante el método MessagingCenter.Send, mientras que los suscriptores escuchan mensajes mediante el método MessagingCenter.Subscribe. Además, los suscriptores también pueden cancelar la suscripción de mensajes, si es necesario, con el método MessagingCenter.Unsubscribe.

Importante

Internamente, la clase MessagingCenter usa referencias débiles. Esto significa que no mantendrá vivos los objetos y permitirá que sean recolectados por el recolector de basura. Por lo tanto, solo debe ser necesario cancelar la suscripción de un mensaje cuando una clase ya no desea recibir el mensaje.

Publicar un mensaje

Los mensajes MessagingCenter son cadenas. Los publicadores notifican a los suscriptores un mensaje con una de las sobrecargas de MessagingCenter.Send. En el ejemplo de código siguiente se publica un mensaje de Hi:

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

En este ejemplo, el método Send especifica un argumento genérico que representa al remitente. Para recibir el mensaje, un suscriptor también debe especificar el mismo argumento genérico, lo que indica que escuchan un mensaje de ese remitente. Además, en este ejemplo se especifican dos argumentos de método:

  • El primer argumento especifica la instancia del remitente.
  • El segundo argumento especifica el mensaje.

Los datos de carga también se pueden enviar con un mensaje:

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

En este ejemplo, el método Send especifica dos argumentos genéricos. El primero es el tipo que envía el mensaje y el segundo es el tipo de los datos de carga que se envían. Para recibir el mensaje, un suscriptor también debe especificar los mismos argumentos genéricos. Esto permite que distintos suscriptores reciban varios mensajes que comparten una identidad de mensaje, pero envían diferentes tipos de datos de carga. Además, en este ejemplo se especifica un tercer argumento de método que representa los datos de carga que se enviarán al suscriptor. En este caso, los datos de carga son un string.

El método Send publicará el mensaje y los datos de carga, mediante un enfoque de disparo y olvido. Por lo tanto, el mensaje se envía incluso si no hay suscriptores registrados para recibir el mensaje. En esta situación, se omite el mensaje enviado.

Suscribirse a un mensaje

Los suscriptores pueden registrarse para recibir un mensaje mediante una de las sobrecargas de MessagingCenter.Subscribe. En el ejemplo de código siguiente se muestra un ejemplo de esto:

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

En este ejemplo, el método Subscribe suscribe el objeto this a mensajes Hi enviados por el tipo MainPage y ejecuta un delegado de callback en respuesta a la recepción del mensaje. El delegado de devolución de llamada, especificado como una expresión lambda, podría ser el código que actualice la interfaz de usuario, guarde ciertos datos o desencadene alguna otra operación.

Nota

Es posible que un suscriptor no necesite controlar todas las instancias de un mensaje publicado y esto se puede controlar mediante los argumentos de tipo genérico que se especifican en el método Subscribe.

En el ejemplo siguiente se muestra cómo suscribirse a un mensaje que contiene datos de carga:

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

En este ejemplo, el método Subscribe se suscribe a mensajes Hi enviados por el tipo MainPage, cuyos datos de carga son un string. Se ejecuta un delegado de callback en respuesta a la recepción de este mensaje, que muestra los datos de la carga útil en una alerta.

Importante

El delegado ejecutado por el método Subscribe se ejecutará en el mismo subproceso que publica el mensaje mediante el método Send.

Cancelar la suscripción de un mensaje

Los suscriptores pueden cancelar la suscripción a los mensajes que ya no quieren recibir. Esto se logra con una de las sobrecargas de MessagingCenter.Unsubscribe:

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

En este ejemplo, el método Unsubscribe cancela la suscripción del objeto this del mensaje Hi enviado por el tipo MainPage.

Los mensajes que contienen datos de carga útil deben darse de baja mediante la sobrecarga Unsubscribe que especifica dos argumentos genéricos.

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

En este ejemplo, el método Unsubscribe cancela la suscripción del objeto this al mensaje Hi enviado por el tipo MainPage, cuyos datos de carga son un string.