共用方式為


Xamarin.Forms MessagingCenter

發行-訂閱模式是一種訊息模式,發行者可以在不知道任何接收者 (稱為訂閱者) 的情況下傳送訊息。 同樣地,訂閱者可以在不知道任何發行者的情況下接聽特定訊息。

.NET 中的事件會實作發佈-訂閱模式,如果不需要鬆散結合,則元件之間的通訊層是最簡單且直接的方法,例如控件和包含它的頁面。 不過,發行者和訂閱者存留期會藉由物件參考彼此藕合,而訂閱者類型必須具有發行者類型的參考。 這可以建立記憶體管理問題,特別是當有短期物件訂閱靜態或長時間存留物件的事件時。 如果未移除事件處理常式,訂閱者將會由發行者中的參考保持運作,這樣可防止或延遲訂閱者的記憶體回收。

類別 Xamarin.FormsMessagingCenter 會實作發佈-訂閱模式,允許元件之間的訊息式通訊,這些元件無法依物件和型別參考連結。 此機制讓發行者和訂閱者不需彼此參考就能進行通訊,有助於減少兩者之間的相依性。

MessagingCenter 類別提供多點傳送的發行-訂閱功能。 這表示可以有多個發行單一訊息的發行者,而且可以有多個接聽相同訊息的訂閱者:

多點傳送的發行-訂閱功能

發行者會使用 MessagingCenter.Send 方法來傳送訊息,而訂閱者會使用 MessagingCenter.Subscribe 方法來接聽訊息。 此外,訂閱者也可以在必要時,使用 MessagingCenter.Unsubscribe 方法,取消訂閱訊息訂閱。

重要

在內部,MessagingCenter 類別會使用弱式參考。 這表示它將不會讓物件持續運作,並將允許它們進行記憶體回收。 因此,應該只有當類別不再希望收到訊息時,才需要取消訂閱訊息。

發行訊息

MessagingCenter 訊息為字串。 發行者會使用其中一個 MessagingCenter.Send 多載來通知訊息的訂閱者。 下列程式碼範例會發行 Hi 訊息:

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

在此範例中,Send 方法會指定代表傳送者的泛型引數。 若要接收訊息,訂閱者也必須指定相同的泛型引數,表示它們正在接聽來自該傳送者的訊息。 此外,此範例會指定兩個方法引數:

  • 第一個引數會指定傳送者執行個體。
  • 第二個引數會指定訊息。

承載資料也可以與訊息一起傳送:

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

在此範例中,Send 方法會指定兩個泛型引數。 第一個是傳送訊息的類型,而第二個是要傳送的承載資料類型。 若要接收訊息,訂閱者也必須指定相同的泛型引數。 這會啟用多則訊息,這類訊息會共用一個訊息識別碼,但傳送不同的承載資料類型以供不同的訂閱者接收。 此外,此範例會指定第三個方法引數,表示要傳送給訂閱者的承載資料。 在此案例中,承載資料為 string

Send 方法將使用射後不理方法來發行訊息和任何承載資料。 因此,即使沒有任何訂閱者已註冊要接收訊息,也會傳送訊息。 在此情況下,會忽略已傳送的訊息。

訂閱訊息

訂閱者可以註冊,以使用其中一個 MessagingCenter.Subscribe 多載來接收訊息。 下列程式碼範例示範此作法的範例:

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

在此範例中,Subscribe 方法會將 this 物件訂閱至 MainPage 類型所傳送的 Hi 訊息,並執行回呼委派以回應接收訊息。 指定為 Lambda 運算式的回呼委派可以是更新 UI、儲存一些資料或觸發一些其他作業的程式碼。

注意

訂閱者可能不需要處理已發行訊息的每個執行個體,而且這可由 Subscribe 方法中指定的泛型類型引數來控制。

下列範例示範如何訂閱包含承載資料的訊息:

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

在此範例中,Subscribe 方法會訂閱 MainPage 類型所傳送的 Hi 訊息,其承載資料為 string。 回呼委派會執行以回應接收這類訊息,其會在警示中顯示承載資料。

重要

方法所 Subscribe 執行的委派將會在使用 Send 方法發行訊息的相同線程上執行。

從訊息中取消訂閱

若訂閱者不想再接收訊息,則應從訊息中取消訂閱。 這會使用其中一個 MessagingCenter.Unsubscribe 多載來達成:

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

在此範例中,Unsubscribe 方法會從 MainPage 類型所傳送的 Hi 訊息中取消訂閱 this 物件。

包含承載資料的訊息應使用指定兩個泛型引數的 Unsubscribe 多載來取消訂閱:

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

在此範例中,Unsubscribe 方法會從 MainPage 類型所傳送的 Hi 訊息中取消訂閱 this 物件,其承載資料為 string