Xamarin form MessagingCenter Unsubscribe is not wo

2020-08-26 03:17发布

问题:

Functionality written inside the MessagingCenter.Subscribe() is called multiple times when i navigate to and fro multiple times in the application. But each time before subscribing, i do unsubscribe to the same in constructor as follows, still it didn't worked.

MessagingCenter.Unsubscribe<SubmitPage>(this,"Save");
MessagingCenter.Subscribe<SubmitPage>(this, "Save", (sender) =>
{
   DisplayToastOnSuccessfulSubmission();
});

In my application i have 6 pages(git) and i save the data in 6th page with MessagingCenter.Send and same will be subscribed in 2nd page and saved message will be displayed in 2nd page(after navigating to that page).

Now i navigate like 2->1->2->3->4->5->6 in this particular case DisplayToastOnSuccessfulSubmission() would be called two times(because Page2 constructor is called twice).

I even tried placing the same code in OnAppearing. I can't unsubscribe in OnDisappear as I need the event wiring up to when I reach Page6 for save.

Reproduced the same behaviour in sample project and added here https://github.com/suchithm/MessageCenterSampleApp
Drop box link

What is the proper way to do this?

回答1:

But each time before subscribing, I do unsubscribe to the same in constructor as follows, still it didn't worked.

MessagingCenter.Subscribe() is called multiple times, because there are two instances of Page2 in your code, both of them use MessagingCenter.Subscribe() method, that's why the Unsubscribe didn't work.

You can modify page2() to a singleton to make sure there is only one instance of Page2 in your project, after that when you send a message, the MessagingCenter.Subscribe() is called only once.

Page2.cs:

public static Page2 instance = new Page2();

public static Page2 GetPage2Instance()
{
    if(instance == null)
    {
        return new Page2();
    }
    return instance;
}

private Page2()
{
    InitializeComponent();
    MessagingCenter.Unsubscribe<Page2>(this, "SaveToastPage2");
    MessagingCenter.Subscribe<Page2>(this, "SaveToastPage2", (sender) =>
    {
       DisplayToastOnSuccessfulSubmission();
    }
 }

When you send a message :

MessagingCenter.Send(Page2.GetPage2Instance(), "SaveToastPage2");

EDIT :

Remember that declaring constructors of Page2 class to be private to make sure there is only one instance of Page2 in your project sure.

private Page2()
{
   ...
}

Modify your Page1.cs code :

async void Handle_Next(object sender, System.EventArgs e)
{
    await App.NavigationRef.PushAsync(Page2.GetPage2Instance(), true);
}


回答2:

Instead of unsubscribing when you navigate TO a page, unsubscribe when you navigate AWAY from the page. At that point your instance of 'this' is still the same 'this' you think it is.



回答3:

I faced same issue. I solved issue by passing the same parameters inn subscribe and unsubscribing as well.

MessagingCenter.Subscribe<Page1, T>(this, "Listen", async (Page1 arg1, T 
listenedString) =>
{

});

Unsubscribe like below

 MessagingCenter.Unsubscribe<Page1, T>(this, "Listen");